diff --git a/.gitignore b/.gitignore index eddec8274..f3a7df325 100644 --- a/.gitignore +++ b/.gitignore @@ -26,8 +26,6 @@ wnprc_billing/resources/credits/jars.txt .storybook-out/ -docker/ehrcron/scripts/pg_backup/lkbackup.ini - # generated artifacts from @labkey/build */resources/web/*/gen/ */resources/views/gen/ diff --git a/DBUtils/resources/credits/jars.txt b/DBUtils/resources/credits/jars.txt index f6131df2d..51c096f68 100644 --- a/DBUtils/resources/credits/jars.txt +++ b/DBUtils/resources/credits/jars.txt @@ -1,5 +1,5 @@ {table} -Filename|Component|Version|Source|License|LabKey Dev|Purpose +Filename|Component|Version|Source|License|Dev|Purpose jooq-3.8.4.jar|jOOQ|3.8.4|{link:From GitHub|https://github.com/jOOQ/jOOQ}|{link:Apache Software License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|jrichardson|Database-mapping for Java jaxb-api-2.3.0.jar|jaxb|2.3.0|Oracle|{link:CDDL 1.1|https://oss.oracle.com/licenses/CDDL+GPL-1.1}{link:GPL2w/ CPE|https://oss.oracle.com/licenses/CDDL+GPL-1.1}|klum|Parsing XML {table} diff --git a/DeviceProxy/resources/credits/jars.txt b/DeviceProxy/resources/credits/jars.txt index 988c499c1..1376d436d 100644 --- a/DeviceProxy/resources/credits/jars.txt +++ b/DeviceProxy/resources/credits/jars.txt @@ -1,5 +1,5 @@ {table} -Filename|Component|Version|Source|License|LabKey Dev|Purpose +Filename|Component|Version|Source|License|Dev|Purpose jooq-3.8.4.jar|jOOQ|3.8.4|{link:From GitHub|https://github.com/jOOQ/jOOQ}|{link:Apache Software License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|jrichardson|Database-mapping for Java jaxb-api-2.3.0.jar|Java Architecture for XML Binding (JAXB)|2.3.0|Oracle|{link:CDDL|https://oss.oracle.com/licenses/CDDL}|klum|Parsing XML {table} diff --git a/GoogleDrive/resources/credits/jars.txt b/GoogleDrive/resources/credits/jars.txt index e8e8a135f..d52b3bf51 100644 --- a/GoogleDrive/resources/credits/jars.txt +++ b/GoogleDrive/resources/credits/jars.txt @@ -1,5 +1,5 @@ {table} -Filename|Component|Version|Source|License|LabKey Dev|Purpose -google-api-client-1.22.0.jar|Google APIs Client Library for Java|1.22.0|{link:From GitHub|https://github.com/google/google-api-java-client}|{link:Apache Software License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|jrichardson|Used to connect to Google Drive +Filename|Component|Version|Source|License|WNPRC Dev|Purpose +google-api-client-1.23.0.jar|Google APIs Client Library for Java|1.23.0|{link:From GitHub|https://github.com/google/google-api-java-client}|{link:Apache Software License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|jrichardson|Used to connect to Google Drive google-api-services-drive-v3-rev85-1.23.0.jar|Google Drive API Client Library for Java|v3 rev85 1.23.0|{link:From Google|https://developers.google.com/api-client-library/java/apis/drive/v3}|{link:Apache Software License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|jrichardson|Used to connect to Google Drive {table} \ No newline at end of file diff --git a/WNPRC_Compliance/module.properties b/WNPRC_Compliance/module.properties index 8378dbcc8..97cb3c7ae 100644 --- a/WNPRC_Compliance/module.properties +++ b/WNPRC_Compliance/module.properties @@ -4,6 +4,6 @@ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 ModuleClass: org.labkey.wnprc_compliance.WNPRC_ComplianceModule Name: WNPRC_Compliance -SchemaVersion: 20.000 +SchemaVersion: 21.001 SupportedDatabases: pgsql ManageVersion: false diff --git a/WNPRC_Compliance/resources/schemas/dbscripts/postgresql/wnprc_compliance-21.000-21.001.sql b/WNPRC_Compliance/resources/schemas/dbscripts/postgresql/wnprc_compliance-21.000-21.001.sql new file mode 100644 index 000000000..d5d6eef94 --- /dev/null +++ b/WNPRC_Compliance/resources/schemas/dbscripts/postgresql/wnprc_compliance-21.000-21.001.sql @@ -0,0 +1,5 @@ +ALTER TABLE wnprc_compliance.measles_clearances ADD COLUMN IF NOT EXISTS required BOOLEAN DEFAULT true; + +ALTER TABLE wnprc_compliance.persons ADD COLUMN IF NOT EXISTS hold BOOLEAN DEFAULT false; +--update measles_required from wnprc_compliance.measles_clearances using labkey javascript API +ALTER TABLE wnprc_compliance.persons ADD COLUMN IF NOT EXISTS measles_required BOOLEAN DEFAULT false; diff --git a/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml b/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml index 1ba2b3d2d..80be1b01e 100644 --- a/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml +++ b/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml @@ -106,6 +106,8 @@ + + diff --git a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/view/unidentifiedCards.jsp b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/view/unidentifiedCards.jsp index b89e620e9..c6b020adf 100644 --- a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/view/unidentifiedCards.jsp +++ b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/view/unidentifiedCards.jsp @@ -217,7 +217,7 @@ WebUtils.VM.submitMarkExempt = function() { $exemptDialog.modal('hide'); var cardData = ko.mapping.toJS(WebUtils.VM.form); - WebUtils.API.postJSON("<%=q(urlFor(MarkCardExemptAPI.class))%>", { + WebUtils.API.postJSON(<%=q(urlFor(MarkCardExemptAPI.class))%>, { cardId: cardData.selectedCard[0], reason: cardData.notes }).then(function(d) { @@ -236,7 +236,7 @@ //TODO validate here... //TODO not sure how this $parent selectedPerson really works here? - WebUtils.API.postJSON("<%=q(urlFor(WNPRC_ComplianceController.LinkCardAPI.class))%>", { + WebUtils.API.postJSON(<%=q(urlFor(WNPRC_ComplianceController.LinkCardAPI.class))%>, { cardId: cardData.selectedCard[0], personId: personData.selectedPerson }).then(function(d) { @@ -285,7 +285,7 @@ } else { // knockout wasn't playing nice here, using jQuery to force button to disabled $(document).on('click', '#radio-person', function () { - $('#link-card-button').removeProp('disabled'); + $('#link-card-button').prop('disabled', false); }); } WebUtils.VM.listPersons.userMatches((PERSONS in results) ? results[PERSONS] : []); diff --git a/WNPRC_EHR/resources/credits/jars.txt b/WNPRC_EHR/resources/credits/jars.txt index 061fb4c99..f64477d89 100644 --- a/WNPRC_EHR/resources/credits/jars.txt +++ b/WNPRC_EHR/resources/credits/jars.txt @@ -1,6 +1,14 @@ {table} -Filename|Component|Version|Source|License|LabKey Dev|Purpose +Filename|Component|Version|Source|License|WNPRC Dev|Purpose joda-time-2.8.1.jar|Joda-Time|2.8.1|{link:From GitHub|https://github.com/JodaOrg/joda-time}|{link:Apache Software License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|jrichardson|Tools for dealing with dates/times in Java -jsoup-1.10.3.jar|jsoup: Java HTML Parser|1.10.3|{link:From GitHub|https://github.com/jhy/jsoup}|{link:MIT License|https://opensource.org/licenses/MIT}|jricharson|Tools for parsing and manipulating HTML and CSS using the DOM +jsoup-1.13.1.jar|jsoup: Java HTML Parser|1.10.3|{link:From GitHub|https://github.com/jhy/jsoup}|{link:MIT License|https://opensource.org/licenses/MIT}|jricharson|Tools for parsing and manipulating HTML and CSS using the DOM reflections-0.9.10.jar|Reflections|0.9.10|{link:From GitHub|https://github.com/ronmamo/reflections}|{link:WTFPL|http://www.wtfpl.net/about/}|cstevens|Runtime analysis of Java classes and packages -{table} +google-api-client-1.23.0.jar|Google API Client for Java|1.30.5|{link:GitHub|https://github.com/googleapis/google-api-java-client}|{link:Apache License 2.0|https://github.com/googleapis/google-api-java-client/blob/master/LICENSE}|ggottfredsen|Library to interact with Google APIs +google-api-services-calendar-v3-rev255-1.23.0.jar|Google Calendar API Client Library for Java|v3-rev20210708-1.32.1|{link:GitHub|https://github.com/googleapis/google-api-java-client-services/tree/master/clients/google-api-services-calendar/v3}|{link:Apache License 2.0|http://www.apache.org/licenses/LICENSE-2.0}|ggottfredsen|Library for interacting with Google Calendars in Java +google-http-client-gson-1.23.0.jar|Google HTTP Client Library for Java|1.39.2-sp.1|{link:GitHub|https://github.com/googleapis/google-http-java-client/tree/master/google-http-client-gson}|{link:Apache License 2.0|https://github.com/googleapis/google-http-java-client/blob/master/LICENSE}|ggottfredsen|A flexible, efficient, and powerful Java library for accessing any resource on the web via HTTP +google-auth-library-oauth2-http-0.19.0.jar|Google Auth Library|1.0.0|{link:GitHub|https://github.com/googleapis/google-auth-library-java/tree/master/oauth2_http}|{link:BSD 3-Clause "New" or "Revised" License|https://github.com/googleapis/google-auth-library-java/blob/master/LICENSE}|ggottfredsen|Contains a wide variety of credentials as well as utility methods to create them and to get Application Default Credentials +commons-text-1.9.jar|Apache Commons Text|1.9|{link:GitHub|https://github.com/apache/commons-text}|{link:Apache License 2.0|https://github.com/apache/commons-text/blob/master/LICENSE.txt}|ggottfredsen|A library focused on algorithms working on strings +msal4j-1.11.0.jar|Microsoft Authentication Library (MSAL) for Java|1.11.0|{link:GitHub|https://github.com/AzureAD/microsoft-authentication-library-for-java}|{link:MIT License|https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/dev/LICENSE}|ggottfredsen|Allows to sign in users or apps with Microsoft identities (Azure AD, Microsoft accounts and Azure AD B2C accounts) and obtain tokens to call Microsoft APIs such as Microsoft Graph +microsoft-graph-2.10.0.jar|Microsoft Graph Java SDK|2.10.0|{link:GitHub|https://github.com/microsoftgraph/msgraph-sdk-java}|{link:MIT License|https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/LICENSE}|ggottfredsen|Allows for interacting with Microsoft Graph (Calendars/User Accounts/Email/etc.) +slf4j-nop-1.8.0-beta4.jar|Simple Logging Facade for Java|1.8.0-beta4|{link:GitHub|https://github.com/qos-ch/slf4j/tree/master/slf4j-nop}|{link:MIT License|https://github.com/qos-ch/slf4j/blob/master/LICENSE.txt}|ggottfredsen|Abstraction for various logging frameworks allowing for plugging in a desired framework at deployment time +{table} \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/Biopsy/.qview.xml b/WNPRC_EHR/resources/queries/study/Biopsy/.qview.xml index db3021f06..dc6386822 100644 --- a/WNPRC_EHR/resources/queries/study/Biopsy/.qview.xml +++ b/WNPRC_EHR/resources/queries/study/Biopsy/.qview.xml @@ -6,6 +6,7 @@ + diff --git a/WNPRC_EHR/resources/queries/study/Demographics.query.xml b/WNPRC_EHR/resources/queries/study/Demographics.query.xml index 50138b230..64bd32968 100644 --- a/WNPRC_EHR/resources/queries/study/Demographics.query.xml +++ b/WNPRC_EHR/resources/queries/study/Demographics.query.xml @@ -81,6 +81,12 @@ /ehr/participantView.view?participantId=${dam} + + true + + + true + Sire @@ -92,6 +98,9 @@ + + true + yyyy-MM-dd @@ -102,6 +111,9 @@ query.Id~eq=${Id} + + true + yyyy-MM-dd @@ -214,6 +226,9 @@ + + true + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/WaterOrders/activeWaterOrders.qview.xml b/WNPRC_EHR/resources/queries/study/WaterOrders/activeWaterOrders.qview.xml new file mode 100644 index 000000000..cefda070c --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/WaterOrders/activeWaterOrders.qview.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/WaterRecentWeight.sql b/WNPRC_EHR/resources/queries/study/WaterRecentWeight.sql new file mode 100644 index 000000000..0cfd964dd --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/WaterRecentWeight.sql @@ -0,0 +1,27 @@ +SELECT +voGi.id, +CAST (voGi.date AS DATE) AS Date, +voGi.volume, +voGi.RecentWeight, +voGi.InnerWeight, +voGi.objectid +--voGi.DayDiff + +FROM ( + +SELECT + wa.id AS id, + wa.date AS date, + wa.volume, + (SELECT we.weight + FROM study.weight we + --INNER JOIN study.weight wein + --ON we.id = wein.id + WHERE we.id = wa.id AND we.date = (SELECT MAX(wen.date) from study.weight wen WHERE wen.id=wa.id AND timestampdiff('SQL_TSI_DAY',wa.date,wen.date)<=0))AS InnerWeight, + (SELECT MAX(wen.date) from study.weight wen WHERE wen.id=wa.id AND timestampdiff('SQL_TSI_DAY',wa.date,wen.date)<=0) AS RecentWeight, + wa.objectid + --timestampdiff('SQL_TSI_DAY',wa.date ,wa.RecentWeight) AS DayDiff + + FROM study.waterGiven wa +) voGi +--GROUP BY voGi.id, voGi.date,voGi.RecentWeight,voGi.InnerWeight \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/WaterScheduleWithWeight.sql b/WNPRC_EHR/resources/queries/study/WaterScheduleWithWeight.sql new file mode 100644 index 000000000..f90306875 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/WaterScheduleWithWeight.sql @@ -0,0 +1,41 @@ +SELECT + lsid AS lsid, + objectid AS objectIdCoalesced, + taskid AS taskid, + project AS projectCoalesced, + animalId AS animalId, + room || '-' || cage AS location, + date AS date, + dateOrdered AS dateOrdered, + startDateCoalesced AS startDateCoalesced, + volume AS volume, + provideFruit AS provideFruit, + provideFruitTitle AS provideFruitTitle, + dataSource AS dataSource, + assignedTo AS assignedToCoalesced, + assignedToTitle AS assignedToTitleCoalesced, + frequency AS frequencyCoalesced, + frequencyMeaning AS frequencyMeaningCoalesced, + timeofday AS timeofday, + displaytimeofday AS displaytimeofday, + qcstate AS qcstate, + + --(SELECT max(wg.qcstate) as label FROM study.waterGiven wg WHERE WCO.objectid = wg.treatmentid AND WCO.dateOrdered = wg.dateordered ) AS waterStatus, + -- (SELECT timestampdiff(SQL_TSI_HOUR,WCO.date,wg.dateordered ) as diff FROM study.waterGiven wg WHERE WCO.objectid = wg.treatmentid ) AS difference, + + (SELECT wg.weight AS weightAtDate + FROM study.weight wg + WHERE wg.id = WCO.animalId AND CAST(substring(CAST(wg.date AS VARCHAR) , 1, 10) AS DATE) <= WCO.date + ORDER BY wg.date DESC + LIMIT 1 + ) AS weightAtDate, + + (SELECT wg.date AS weightDate + FROM study.weight wg + WHERE wg.id = WCO.animalId AND CAST(substring(CAST(wg.date AS VARCHAR) , 1, 10) AS DATE) <= WCO.date + ORDER BY wg.date DESC + LIMIT 1 + ) AS weightDate + +FROM study.waterScheduleCoalesced WCO +--WHERE WCO.dateRangeStartDate >= curdate() \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/biopsy.query.xml b/WNPRC_EHR/resources/queries/study/biopsy.query.xml index bf1262b80..9e28ac25f 100644 --- a/WNPRC_EHR/resources/queries/study/biopsy.query.xml +++ b/WNPRC_EHR/resources/queries/study/biopsy.query.xml @@ -15,6 +15,9 @@ NHPBMD + + Billing Complete + Final Summary Comments diff --git a/WNPRC_EHR/resources/queries/study/chairing.js b/WNPRC_EHR/resources/queries/study/chairing.js new file mode 100644 index 000000000..77601acae --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/chairing.js @@ -0,0 +1,90 @@ +require("ehr/triggers").initScript(this); +var WNPRC = require("wnprc_ehr/WNPRC").WNPRC; +require ("labkey"); + +function onInit(event, helper){ + helper.decodeExtraContextProperty('clientEncounterDate'); + + helper.registerRowProcessor(function(helper,row) { + if (!row) + return; + if(!row.Id || !row.date){ + return; + } + var clientEncounterDate = helper.getProperty('clientEncounterDate'); + clientEncounterDate = clientEncounterDate || {}; + clientEncounterDate[row.Id] = clientEncounterDate [row.Id] || []; + + if (row.objectid) { + LABKEY.ExtAdapter.each(clientEncounterDate[row.Id], function (r) { + if (r.objectid == row.objectid) { + if (r.date != row.date) { + r.date = row.date; + } + else { + return false; + } + } + }, this) + } + helper.setProperty('clientEncounterDate', clientEncounterDate); + }); +} +function onUpsert(helper, scriptErrors, row, oldRow){ + + if (row.chairingStartTime){ + var map = helper.getProperty('clientEncounterDate'); + var clientEncounterDate = []; + if (map && map[row.Id]){ + //console.log(map[row.Id]); + clientEncounterDate = map[row.Id]; + + } + let errorMessage = WNPRC.Utils.getJavaHelper().checkEncounterTime(row.Id,row.chairingStartTime,clientEncounterDate, 'chairing'); + if (errorMessage != null){ + EHR.Server.Utils.addError(scriptErrors,'chairingStartTime',errorMessage,'ERROR'); + } + + } + + if (row.chairingEndTime){ + var map = helper.getProperty('clientEncounterDate'); + var clientEncounterDate = []; + if (map && map[row.Id]){ + //console.log(map[row.Id]); + clientEncounterDate = map[row.Id]; + + } + let errorMessage = WNPRC.Utils.getJavaHelper().checkEncounterTime(row.Id,row.chairingEndTime,clientEncounterDate, 'chairing'); + if (errorMessage != null){ + EHR.Server.Utils.addError(scriptErrors,'chairingEndTime',errorMessage,'ERROR'); + } + + } + + var startChairing = new Date (row.chairingStartTime.toGMTString()); + var endChairing = new Date (row.chairingEndTime.toGMTString()); + + + var _MS_PER_HOUR = 1000 * 60 * 60; + + var timeDifference = parseInt(Math.ceil((endChairing - startChairing)/_MS_PER_HOUR)); + + if (timeDifference >12){ + + EHR.Server.Utils.addError(scriptErrors, 'chairingEndTime', 'An animal cannot be chaired for longer than 12 hours', 'ERROR'); + + } + if (timeDifference == 0){ + EHR.Server.Utils.addError(scriptErrors, 'chairingEndTime', 'Chairing End time cannot be the same as Start time', 'ERROR'); + } + + //console.log ('chairing start time: '+ startChairing); + //console.log ('chairing end time: '+ endChairing); + + if (endChairing < startChairing){ + EHR.Server.Utils.addError(scriptErrors,'chairingEndTime', 'End time cannot be before the Start time', 'ERROR'); + } + + +} diff --git a/WNPRC_EHR/resources/queries/study/chairing.query.xml b/WNPRC_EHR/resources/queries/study/chairing.query.xml new file mode 100644 index 000000000..db1b6ff4b --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/chairing.query.xml @@ -0,0 +1,40 @@ + + + +
+ + + + + + caseno + + + + Chairing Start Time + Chairing Start Time + yyyy-MM-dd HH:mm + + + + Chairing End Time + Chairing End Time + yyyy-MM-dd HH:mm + + + + Chairing Location + Chairing Location + + ehr_lookups + water_location + value + + + + + chairing +
+ + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/demographicsMostRecentWaterCondition.query.xml b/WNPRC_EHR/resources/queries/study/demographicsMostRecentWaterCondition.query.xml new file mode 100644 index 000000000..871d67700 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/demographicsMostRecentWaterCondition.query.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + Start Date + yyyy-MM-dd + + + + Condition + + ehr_lookups + water_source + value + title + + + +
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/demographicsMostRecentWaterCondition.sql b/WNPRC_EHR/resources/queries/study/demographicsMostRecentWaterCondition.sql new file mode 100644 index 000000000..ccc80310d --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/demographicsMostRecentWaterCondition.sql @@ -0,0 +1,24 @@ +SELECT + +wsa.id, +wsa.MostRecentWaterConditionDate, +( + SELECT wsainner.mlsperKg + FROM study.waterScheduledAnimals wsainner + WHERE wsa.id = wsainner.id AND wsa.MostRecentWaterConditionDate = wsainner.date + +) AS mlsperKg, +( + SELECT wsainner.condition + FROM study.waterScheduledAnimals wsainner + WHERE wsa.id = wsainner.id AND wsa.MostRecentWaterConditionDate = wsainner.date + +) AS MostRecentWaterCondition +FROM( + SELECT + wsaouter.id as id, + max(wsaouter.date) AS MostRecentWaterConditionDate + FROM study.waterScheduledAnimals wsaouter + WHERE wsaouter.qcstate.publicdata = true AND wsaouter.condition IS NOT NULL + GROUP BY wsaouter.id + ) wsa diff --git a/WNPRC_EHR/resources/queries/study/drug.js b/WNPRC_EHR/resources/queries/study/drug.js new file mode 100644 index 000000000..58da39225 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/drug.js @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2010-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +require("ehr/triggers").initScript(this); +var WNPRC = require("wnprc_ehr/WNPRC").WNPRC; + +function onInit(event,helper){ + helper.decodeExtraContextProperty('clientEncounterDate'); + + helper.registerRowProcessor(function(helper,row) { + //TODO: pull this out and put into generic 'utils' function for reuse in other trigger scripts + if (!row) + return; + if(!row.Id || !row.date){ + return; + } + var clientEncounterDate = helper.getProperty('clientEncounterDate'); + clientEncounterDate = clientEncounterDate || {}; + clientEncounterDate[row.Id] = clientEncounterDate [row.Id] || []; + + if (row.objectid) { + LABKEY.ExtAdapter.each(clientEncounterDate[row.Id], function (r) { + if (r.objectid == row.objectid) { + if (r.date != row.date) { + r.date = row.date; + } + else { + return false; + } + } + }, this) + } + helper.setProperty('clientEncounterDate', clientEncounterDate); + }); + +} +function onUpsert(helper, scriptErrors, row, oldRow){ + if (row.date){ + var map = helper.getProperty('clientEncounterDate'); + var clientEncounterDate = []; + if (map && map[row.Id]){ + clientEncounterDate = map[row.Id]; + + } + + if(clientEncounterDate.length > 0){ + let errorMessage = WNPRC.Utils.getJavaHelper().checkEncounterTime(row.Id, row.date, clientEncounterDate, 'drug'); + if (errorMessage != null) { + EHR.Server.Utils.addError(scriptErrors, 'date', errorMessage, 'ERROR'); + } + } + + } + if (helper.isETL()) + return; + +// if(!row.amount && !row.volume){ +// EHR.Server.Utils.addError(scriptErrors, 'amount', 'Must supply either amount or volume', 'INFO'); +// EHR.Server.Utils.addError(scriptErrors, 'volume', 'Must supply either amount or volume', 'INFO'); +// } + + if (row.qualifier && row.qualifier.match(/\//)){ + EHR.Server.Utils.addError(scriptErrors, 'qualifier', 'This field contains a /. This likely means you need to pick one of the options', 'INFO'); + } + + //we need to store something in the date field during the draft stage, so i use header date + //we swap begindate in here instead + //any form that is an encounter should show begindate, not date + //other forms will not show begindate, so this shouldnt matter here + if (row.begindate) + row.date = row.begindate; + + } diff --git a/WNPRC_EHR/resources/queries/study/drug.query.xml b/WNPRC_EHR/resources/queries/study/drug.query.xml new file mode 100644 index 000000000..1367448de --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/drug.query.xml @@ -0,0 +1,183 @@ + + + + + /ehr/drugDetails.view?lsid=${lsid} + + + + + + + + Begin Date + + + Header Date + DateTime + + + End Time + false + + + + ehr + project + project + + + + Charge Unit + + ehr_lookups + medicationChargeType + value + + + + + Code + + ehr_lookups + snomed + code + + + + Qualifier + + + Reason + + ehr_lookups + drugReason + value + + + + Route + + ehr_lookups + routes + route + + + + + Dosage + + + Dosage Units + + ehr_lookups + dosage_units + unit + + + + + Volume + + + Vol Units + + ehr_lookups + volume_units + unit + + + + + Amount + + + Amount Units + + ehr_lookups + amount_units + unit + + + + + Drug Conc + + + Conc Units + + ehr_lookups + conc_units + unit + + + + + Restraint + + ehr_lookups + restraint_type + type + + + + Time Restrained + + ehr_lookups + restraint_duration + value + + + + Outcome + + ehr_lookups + drugOutcome + value + + + Normal + + + Lot + + + Remark + + + Category + + ehr_lookups + drug_categories + value + + + + + Begin Date + + + Treatment Id + true + + + Time Ordered + For drugs that were ordered using the Treatment Orders table, this stores the original time this administration was scheduled to be administered. + true + + + + + + true + + + ehr_lookups + implant_area + value + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/drug/.qview.xml b/WNPRC_EHR/resources/queries/study/drug/.qview.xml index 141fa24dc..725fc6733 100644 --- a/WNPRC_EHR/resources/queries/study/drug/.qview.xml +++ b/WNPRC_EHR/resources/queries/study/drug/.qview.xml @@ -10,6 +10,7 @@
+ @@ -23,6 +24,7 @@ + diff --git a/WNPRC_EHR/resources/queries/study/restraints.js b/WNPRC_EHR/resources/queries/study/restraints.js index ff0435f5e..d5cbf77a1 100644 --- a/WNPRC_EHR/resources/queries/study/restraints.js +++ b/WNPRC_EHR/resources/queries/study/restraints.js @@ -16,6 +16,11 @@ function onUpdate(helper, scriptErrors, row, oldRow) { } function onUpsert(helper, scriptErrors, row, oldRow) { + if (row.restraintType == 'Other'){ + if(!row.remarks){ + EHR.Server.Utils.addError(scriptErrors, 'remarks', 'Remarks are required when Other is selected from restraint type') + } + } } function setDescription(row, helper){ diff --git a/WNPRC_EHR/resources/queries/study/restraints.query.xml b/WNPRC_EHR/resources/queries/study/restraints.query.xml index a144c4a55..f4d058631 100644 --- a/WNPRC_EHR/resources/queries/study/restraints.query.xml +++ b/WNPRC_EHR/resources/queries/study/restraints.query.xml @@ -13,6 +13,7 @@ Restraint Type + Restraint Type ehr_lookups restraint_type @@ -20,6 +21,7 @@ + restraints diff --git a/WNPRC_EHR/resources/queries/study/treatmentSchedule.query.xml b/WNPRC_EHR/resources/queries/study/treatmentSchedule.query.xml index ed9203741..6bb7e0cd8 100644 --- a/WNPRC_EHR/resources/queries/study/treatmentSchedule.query.xml +++ b/WNPRC_EHR/resources/queries/study/treatmentSchedule.query.xml @@ -1,220 +1,220 @@ - - - - - /EHR/treatmentDetails.view?key=${lsid} - primaryKey - - - true - true - - - true - true - - - true - - - true - - - yyyy-MM-dd - - - - study - animal - Id - - - - - ehr - project - project - - - - Treatment Start Date - yyyy-MM-dd - - - false - SNOMED Code - - ehr_lookups - snomed - code - - - - - - - - - - - true - - ehr_lookups - treatment_frequency - key - - - - 250 - - - 40 - - ehr_lookups - rooms - Room - - - - 40 - - - true - - - true - - core - qcstate - rowid - - - - - - - - - E3170D - - - - - Concentration - - - Amount Given - - - Volume - - - - false - true - Status - 50 - - core - qcstate - rowid - - - - - - - FBEC5D - - - - - - FBEC5D - - - - - - FBEC5D - - - - - - FF0000 - - - - - - FBEC5D - - - - - - FBEC5D - - - - - - FF0000 - - - - - - FBEC5D - - - - - false - Task Id - - ehr - tasks - taskid - - /ehr/taskDetails.view?formtype=${taskid/formtype}&taskid=${taskid} - - - - ehr.context - /ehr/studyButtons.js - EHR.DatasetButtons.moreActionsHandler - - Grid Views - - - Charts - - - Export - - - Print - - - - - EHR.DatasetButtons.historyHandler(dataRegion, dataRegionName); - - - - - - EHR.window.GetDistinctWindow.getDistinctHandler(dataRegionName); - - - - - javascript:void(0); - - -
-
-
+ + + + + /EHR/treatmentDetails.view?key=${lsid} + primaryKey + + + true + true + + + true + true + + + true + + + true + + + yyyy-MM-dd + + + + study + animal + Id + + + + + ehr + project + project + + + + Treatment Start Date + yyyy-MM-dd + + + false + SNOMED Code + + ehr_lookups + snomed + code + + + + + + + + + + + true + + ehr_lookups + treatment_frequency + key + + + + 250 + + + 40 + + ehr_lookups + rooms + Room + + + + 40 + + + true + + + true + + core + qcstate + rowid + + + + + + + + + E3170D + + + + + Concentration + + + Amount Given + + + Volume + + + + false + true + Status + 50 + + core + qcstate + rowid + + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + false + Task Id + + ehr + tasks + taskid + + /ehr/taskDetails.view?formtype=${taskid/formtype}&taskid=${taskid} + + + + ehr.context + /ehr/studyButtons.js + EHR.DatasetButtons.moreActionsHandler + + Grid Views + + + Charts + + + Export + + + Print + + + + + EHR.DatasetButtons.historyHandler(dataRegion, dataRegionName); + + + + + + EHR.window.GetDistinctWindow.getDistinctHandler(dataRegionName); + + + + + javascript:void(0); + + +
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterAmount.js b/WNPRC_EHR/resources/queries/study/waterAmount.js new file mode 100644 index 000000000..2da71cafa --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterAmount.js @@ -0,0 +1,108 @@ +require("ehr/triggers").initScript(this); +var WNPRC = require("wnprc_ehr/WNPRC").WNPRC; + +function onInit(event, helper){ + helper.setScriptOptions({ + allowFutureDates: true + }); + helper.decodeExtraContextProperty('waterInForm'); + helper.decodeExtraContextProperty('clientEncounterDate'); + + helper.registerRowProcessor(function (helper, row){ + if (!row) + return; + if(!row.Id || !row.volume){ + return; + } + + var waterInForm = helper.getProperty('waterInForm'); + waterInForm = waterInForm || {}; + waterInForm[row.Id] = waterInForm[row.Id] || []; + + var clientEncounterDate = helper.getProperty('clientEncounterDate'); + clientEncounterDate = clientEncounterDate || {}; + clientEncounterDate[row.Id] = clientEncounterDate [row.Id] || []; + + if (row.objectid){ + LABKEY.ExtAdapter.each(waterInForm[row.Id], function(r){ + if (r.objectid == row.objectid){ + if(r.volume != row.volume){ + r.volume = row.volume; + } + else{ + return false; + } + } + }, this) + + LABKEY.ExtAdapter.each(clientEncounterDate[row.Id], function(r){ + if (r.objectid == row.objectid){ + if(r.date != row.date){ + r.date = row.date; + } + else{ + return false; + } + } + }, this) + } + helper.setProperty('waterInForm',waterInForm); + helper.setProperty('clientEncounterDate',clientEncounterDate); + }); + +} + +function onUpsert(helper, scriptErrors, row, oldRow) { + + if (row.date){ + var map = helper.getProperty('clientEncounterDate'); + + var clientEncounterDate = []; + if (map && map[row.Id]){ + clientEncounterDate = map[row.Id]; + + } + let errorMessage = WNPRC.Utils.getJavaHelper().checkEncounterTime(row.Id,row.date,clientEncounterDate, 'waterAmount'); + if (errorMessage != null){ + EHR.Server.Utils.addError(scriptErrors,'date',errorMessage,'ERROR'); + } + + } + + if (row.recordSource=="LabWaterForm"){ + var fixdate = new Date(row.date); + fixdate.setHours(14); + fixdate.setMinutes(1); + row.date = fixdate; + if (!row.skipWaterRegulationCheck){ + row.qcstate = EHR.Server.Security.getQCStateByLabel('Scheduled').rowid; + row.QCStateLabel = EHR.Server.Security.getQCStateByLabel('Scheduled').Label; + } + + if (row.assignedTo == "animalcare" && row.volume && !row.skipWaterRegulationCheck){ + let errorMessage = WNPRC.Utils.getJavaHelper().checkUploadTime(row.id,row.date,row.recordSource,row.assignedTo, 'waterAmount'); + if (errorMessage != null){ + EHR.Server.Utils.addError(scriptErrors,'assignedTo',errorMessage,'INFO'); + } + } + if (row.volume && row.waterSource == "regulated" && !row.skipWaterRegulationCheck){ + var map = helper.getProperty('waterInForm'); + var waterInForm = []; + if (map && map[row.Id]){ + waterInForm = map[row.Id]; + } + + let jsonArray = WNPRC.Utils.getJavaHelper().checkWaterSchedule(row.id,row.date,row.objectid,row.volume,waterInForm); + if (jsonArray != null){ + for (var i = 0; i < jsonArray.length; i++ ){ + let errorObject = JSON.parse(jsonArray[i]); + EHR.Server.Utils.addError(scriptErrors,errorObject.field, errorObject.message,errorObject.severity); + + } + } + + } + + } + +} \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterAmount.query.xml b/WNPRC_EHR/resources/queries/study/waterAmount.query.xml new file mode 100644 index 000000000..adf64a79b --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterAmount.query.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + Date Ordered + yyyy-MM-dd HH:mm + + + + + + Volume (mL) + + + Provide Fruit + + ehr_lookups + husbandry_fruit + Value + + + + Assigned To + + ehr_lookups + husbandry_assigned + Value + + + + Frequency + + wnprc + husbandry_frequency + rowid + + + + Water Source + + ehr_lookups + water_source + value + title + + + + Record Source + + + + + +
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/waterGiven.js b/WNPRC_EHR/resources/queries/study/waterGiven.js new file mode 100644 index 000000000..15fe88087 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterGiven.js @@ -0,0 +1,267 @@ +require("ehr/triggers").initScript(this); +var WNPRC = require("wnprc_ehr/WNPRC").WNPRC; + +//EHR.Server.Utils = require("ehr/utils").EHR.Server.Utils; + +function onInit(event, helper){ + //This extracontext is used in the Water Orders form + helper.decodeExtraContextProperty('waterInTransaction'); + //This extracontext is used in the Lab Water form + helper.decodeExtraContextProperty('waterInForm'); + + helper.setScriptOptions({ + allowDeadIds: true, + allowAnyId: true, + skipIdFormatCheck: true, + allowFutureDates: true, + isSkipAssignmentCheck: true + }); + + helper.registerRowProcessor(function(helper, row){ + if (!row) + return; + + if (!row.Id || !row.date){ + return; + } + if (row.taskid){ + + } + + var waterInTransaction = helper.getProperty('waterInTransaction'); + waterInTransaction = waterInTransaction || []; + waterInTransaction[row.Id] = waterInTransaction[row.Id] || []; + + var waterInForm = helper.getProperty('waterInForm'); + waterInForm = waterInForm || {}; + waterInForm[row.Id] = waterInForm[row.Id] || []; + + if (row.objectid) + { + var shouldAdd = true; + LABKEY.ExtAdapter.each(waterInTransaction[row.Id], function (r){ + if (r.objectid == row.objectid){ + if (r.volume != row.volume){ + r.volume = row.volume; + } + else { + shouldAdd = false; + return; + } + } + + }, this); + + LABKEY.ExtAdapter.each(waterInForm[row.Id], function(r){ + if (r.objectid == row.objectid){ + if(r.volume != row.volume){ + r.volume = row.volume; + } + else{ + return false; + } + } + }, this) + } + + if (shouldAdd){ + waterInTransaction[row.Id].push({ + objectid: row.objectid, + date: row.date, + datasource: row.datasource, + qcstate: row.qcstate, + assignedto: row.assignedto, + parentid: row.parentid, + volume: row.volume, + lsid: row.lsid + + }); + } + + helper.setProperty('waterInForm',waterInForm); + helper.setProperty('waterInTransaction', waterInTransaction); + }); +} + +function onUpsert(helper, scriptErrors, row, oldRow) { + /*if (row.volume == null){ + EHR.Server.Utils.addError(scriptErrors, 'volume', 'This field is required', 'WARN'); + console.log ("value of QCState "+ row.QCState) + }*/ + + if (row.QCStateLabel == 'Scheduled'){ + console.log ("value of date given "+ row.date); + EHR.Server.Validation.verifyDate(row, scriptErrors, helper); + + /*if(row.QCStateLabel == 'Scheduled'){ + //TODO: add special condition for water given + currentTimeRounded.setHours(13,30,0,0); + console.log ('RowTime at 1:30 PM '+currentTimeRounded); + console.log ('Rowtime '+ date); + if (date>currentTimeRounded){ + EHR.Server.Utils.addError(errors, 'date', 'Cannot schedule water after 13:30 PM', 'ERROR'); + } + + }*/ + } + + if (row.Id && row.date) + { + // volume is handled differently for requestsvs actual draws + var errorQC = 'ERROR'; + //if (EHR.Server.Security.getQCStateByLabel(row.QCStateLabel)['isRequest'] && !row.taskid) + // errorQC = 'ERROR'; + //else + // errorQC = 'INFO'; + + var map = helper.getProperty('waterInTransaction'); + var waters = []; + if (map && map[row.Id]) + { + waters = map[row.Id]; + /*for (var i=0;i + + + + + + + + + + + + + + yyyy-MM-dd HH:mm + + + yyyy-MM-dd HH:mm + + + Performed By + + + + Volume (mL) + + + + Provide Fruit + + ehr_lookups + husbandry_fruit + value + + + + + + + Water Source + + ehr_lookups + water_source + value + title + + + + Water Location + 250 + + ehr_lookups + water_location + value + + + + Route + + ehr_lookups + routes + route + + + + + Assigned To + + ehr_lookups + husbandry_assigned + value + + + + + + + + + Room + + + + study + demographicsMostRecentWeight + MostRecentWeight + + + + false + + +
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/waterOrders.js b/WNPRC_EHR/resources/queries/study/waterOrders.js new file mode 100644 index 000000000..c5d4ce7be --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterOrders.js @@ -0,0 +1,128 @@ +require("ehr/triggers").initScript(this); +var WNPRC = require("wnprc_ehr/WNPRC").WNPRC; + +function onInit(event, helper){ + helper.setScriptOptions({ + allowFutureDates: true + }); +} + +function onUpsert(helper, scriptErrors, row, oldRow){ + console.log("print oldRow "+ oldRow); + + if (row.Id){ + EHR.Server.Utils.findDemographics({ + participant: row.Id, + helper: helper, + scope: this, + callback: function(data){ + if(data){ + if(!row.project){ + EHR.Server.Utils.addError(scriptErrors, 'project', 'Must enter a project for all center animals.', 'WARN'); + } + } + } + }); + var animalRestricted = {}; + animalRestricted = WNPRC.Utils.getJavaHelper().checkIfAnimalInCondition(row.Id, row.date); + //console.log (animalRestricted); + if (!animalRestricted && !row.skipWaterRegulationCheck){ + EHR.Server.Utils.addError(scriptErrors,'Id', 'Animal not assigned to water restriction protocol or is already in ' + row.waterSource + ' condition.', 'ERROR'); + } + + + + } + + var today = new Date(); + //console.log("Value of date " + row.date); + //console.log("Value of start date " + row.startdate); + today.setHours(0,0,0,0); + + var rowDate = new Date(row.date); + rowDate.setHours(0,0,0,0); + EHR.Server.Utils.removeTimeFromDate(row,scriptErrors,"date"); + + //console.log("Value of date " + rowDate + " "+ rowDate.getTime()); + //console.log("Value of start date " + row.startdate); + //console.log("Value of today "+ today+ " "+ today.getTime()); + + + //TODO: allow updates of existing records. + if(!(rowDate.getTime() >= today.getTime()) && (oldRow.objectid != row.objectid)){ + EHR.Server.Utils.addError(scriptErrors, 'date', 'Only Dates in the Future Allow', 'ERROR'); + } + + var endDate = new Date(row.enddate); + endDate.setHours(0,0,0,0); + + //This does not get checked when the dataset if updated, only when using Ext4 form + if (rowDate.getTime() > endDate.getTime()){ + EHR.Server.Utils.addError(scriptErrors,'endDate', 'EndDate cannot be before StartDate', 'ERROR'); + } + + if (!row.frequency && row.waterSource == 'regulated'){ + EHR.Server.Utils.addError(scriptErrors, 'frequency', 'Frequency is required when entering regulated water orders.', 'ERROR'); + } + if (!row.volume && row.waterSource == 'regulated'){ + //console.log ("water vol "+ row.volume); + EHR.Server.Utils.addError(scriptErrors, 'volume', 'Volume is required when entering regulated water orders.', 'ERROR'); + } + + if (!row.assignedTo && row.waterSource == 'regulated'){ + EHR.Server.Utils.addError(scriptErrors, 'assignedTo', 'Assigned To is required when entering regulated water orders.', 'ERROR'); + } + + if (!row.waterSource){ + EHR.Server.Utils.addError(scriptErrors, 'waterSource', 'Water Source is required when entering new orders.', 'ERROR'); + } + + //console.log ("value of ObjectId "+oldRow.objectid + " Value of new objectId "+ row.objectid); + //console.log ('skipWaterRegulation '+ row.skipWaterRegulationCheck); + // if (oldRow && row.date && row.Id && row.frequency && (oldRow.objectid != row.objectid)) { + if (row.project && row.objectid && row.Id && row.date && row.frequency && row.assignedTo && row.waterSource != 'lixit' && !row.skipWaterRegulationCheck) { + console.log('value of row: frequency ' + row.frequency + ' value of waterSource ' + row.waterSource); + let jsonArray = WNPRC.Utils.getJavaHelper().checkWaterRegulation(row.id, row.date, row.enddate ? row.enddate : null, row.frequency, row.waterSource, row.objectid, row.project, this.extraContext); + if (jsonArray != null) { + for (var i = 0; i < jsonArray.length; i++) { + var errorObject = JSON.parse(jsonArray[i]); + EHR.Server.Utils.addError(scriptErrors, errorObject.field, errorObject.message, errorObject.severity); + } + } + row.date = rowDate; + } + + //if (oldRow && oldRow.waterSource == 'regulated' && row.waterSource == 'lixit'){ + //TODO: by pass water regulation to change water order to lixit and also chnage the water regulated animals data + if ( row.waterSource == 'lixit' && !row.skipWaterRegulationCheck && !oldRow){ + + let jsonArray = WNPRC.Utils.getJavaHelper().changeWaterScheduled(row.id,row.date,row.waterSource, row.project, row.objectid,this.extraContext); + let jsonExtraContext = this.extraContext.extraContextArray; + + if (jsonArray != null){ + for (var i=0; i < jsonArray.length; i++){ + let errorObject = JSON.parse(jsonArray[i]); + EHR.Server.Utils.addError(scriptErrors,errorObject.field, errorObject.message, errorObject.severity); + + } + console.log(" Printing Extra Context" + jsonExtraContext); + if (jsonExtraContext != null){ + for (var i = 0; i < jsonExtraContext.length; i++){ + let extraContextObject = jsonExtraContext[i]; + let date = extraContextObject.date; + let dateOnly = new Date(date.getTime()); + dateOnly = dateOnly.getFullYear()+ "-" +dateOnly.getMonth()+ "-" + dateOnly.getDate(); + let infoMessage = "Water Order for "+ row.Id + " started on " + dateOnly + " with frequency of " + extraContextObject.frequency + " and volume of " + extraContextObject.volume + "ml will close."; + //console.log(infoMessage); + EHR.Server.Utils.addError(scriptErrors,"waterSource",infoMessage,"INFO") + + } + + } + + } + } + + + +} diff --git a/WNPRC_EHR/resources/queries/study/waterPivot.query.xml b/WNPRC_EHR/resources/queries/study/waterPivot.query.xml new file mode 100644 index 000000000..9c808d2ff --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterPivot.query.xml @@ -0,0 +1,33 @@ + + + + + Water Grid + + + + + + + + + study + animal + Id + + + + Goals For Day + + /EHR/cageDetails.view? + room=${room}& + cage=${cage}& + + + + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterPivot.sql b/WNPRC_EHR/resources/queries/study/waterPivot.sql new file mode 100644 index 000000000..60094941c --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterPivot.sql @@ -0,0 +1,25 @@ +SELECT +--wa.id, wa.Date, wa.amountGivenInLab, wa.amountGivenInCage, wa.total, wa.weight +wp.id, +CAST (wp.date AS DATE) AS Date, + +--max(wa.amount) AS goal, +CAST(COALESCE ((SELECT SUM (CAST (iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wp.id AND (dayofyear(iwg.date)-dayofyear(wp.date)) =0 AND iwg.assignedto LIKE 'laboratory'),0) AS NUMERIC) AS volumeGivenInLab, +CAST(COALESCE ((SELECT SUM (CAST (iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wp.id AND (dayofyear(iwg.date)-dayofyear(wp.date)) =0 AND iwg.assignedto LIKE 'animalcare'),0) AS NUMERIC) AS volumeGivenInCage, + +CAST((SELECT SUM (CAST (iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wp.id AND (dayofyear(iwg.date)-dayofyear(wp.date)) =0) AS NUMERIC) AS Total, +CAST(((SELECT SUM (CAST (iwg.volume AS NUMERIC)) + FROM study.waterGiven iwg + WHERE iwg.id=wp.id AND (dayofyear(iwg.date)-dayofyear(wp.date)) =0)-(20*(SELECT dm.id.MostRecentWeight.MostRecentWeight AS MostRecentWieght FROM study.demographics dm WHERE wp.id = dm.id))) AS NUMERIC) AS Weight +--sum(wp.Weight) AS Weight + +FROM study.waterGiven wp + +--WHERE wp.Date > '2015-02-13' and wp.id='r02086' + +GROUP BY wp.id, wp.date +--GROUP BY wa.id, wa.date, wa.volumeGivenInLab, wa.volumeGivenInCage, wa.total, wa.weight + +--PIVOT goal BY id +PIVOT Weight,total,volumeGivenInLab, volumeGivenInCage BY id +--PIVOT weight,total BY id \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterPrePivot.query.xml b/WNPRC_EHR/resources/queries/study/waterPrePivot.query.xml new file mode 100644 index 000000000..e2ca1c8ab --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterPrePivot.query.xml @@ -0,0 +1,72 @@ + + + + + Water Grid + + + + + + + + + study + animal + Id + + + + Goals For Day + + /EHR/cageDetails.view? + room=${room}& + cage=${cage}& + + + + + + + core + QCState + rowId + Label + + + + + + + + + FF0000 + + + + + ml Water Per Kg + + + + + + E74C3C + + + + + + + + Allowed MlsPerKg + + + Date of Allowed MlsPerKg + + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterPrePivot.sql b/WNPRC_EHR/resources/queries/study/waterPrePivot.sql new file mode 100644 index 000000000..6c8460d33 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterPrePivot.sql @@ -0,0 +1,75 @@ +SELECT DISTINCT +voGi.id as animalId, +CAST (voGi.date AS DATE) AS date, +--voGi.projectConcat AS projectConcat, +voGi.performedConcat AS performedConcat, +CAST (voGi.qcstateConcat AS INTEGER) AS qcstate, + +voGi.volumeGivenInLabSub, +voGi.volumeGivenInCage, +voGi.volumeGivenInImage, +voGi.volumeGivenInProcedure, + +voGi.TotalWater AS TotalWater, +voGi.TotalWater AS volume, +voGi.RecentWeight, +voGi.InnerWeight, + + +TRUNCATE(ROUND(CAST(voGi.TotalWater /voGi.InnerWeight AS NUMERIC),2),2) AS mlsPerKg, +voGi.InnerWeight*voGi.InnerMlsPerKg - voGi.TotalWater AS WaterRemaining, + +voGi.RecentMlsPerKg, +voGi.InnerMlsPerKg, + +'waterGiven' AS dataSource + +FROM ( + + SELECT + wa.id AS id, + wa.date AS date, + --GROUP_CONCAT(DISTINCT wa.project, ';') AS projectConcat, + COALESCE((SELECT GROUP_CONCAT(iwg.performedby, ';') FROM study.waterGiven iwg WHERE iwg.id=wa.id AND (dayofyear(iwg.date)-dayofyear(wa.date)) = 0),' ') AS performedConcat, + COALESCE((SELECT DISTINCT( iwg.qcstate) FROM study.waterGiven iwg WHERE iwg.id=wa.id AND iwg.qcstate.label = 'Completed' AND (dayofyear(iwg.date)-dayofyear(wa.date)) = 0),'22') AS qcstateConcat, + COALESCE ((SELECT SUM(CAST(iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wa.id AND (dayofyear(iwg.date)-dayofyear(wa.date)) = 0 AND iwg.location LIKE 'lab'),0) AS volumeGivenInLabSub, + COALESCE ((SELECT SUM(CAST(iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wa.id AND (dayofyear(iwg.date)-dayofyear(wa.date)) = 0 AND iwg.location LIKE 'animalRoom'),0) AS volumeGivenInCage, + COALESCE ((SELECT SUM(CAST(iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wa.id AND (dayofyear(iwg.date)-dayofyear(wa.date)) = 0 AND iwg.location LIKE 'imaging'),0) AS volumeGivenInImage, + COALESCE ((SELECT SUM(CAST(iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wa.id AND (dayofyear(iwg.date)-dayofyear(wa.date)) = 0 AND iwg.location LIKE 'procedureRoom'),0) AS volumeGivenInProcedure, + COALESCE ((SELECT SUM (CAST (iwg.volume AS NUMERIC)) FROM study.waterGiven iwg WHERE iwg.id=wa.id AND (dayofyear(iwg.date)-dayofyear(wa.date)) =0),0) AS TotalWater, + (SELECT we.weight + FROM study.weight we + WHERE we.id = wa.id AND we.date = ( + SELECT MAX(wen.date) + FROM study.weight wen + WHERE (wen.id=wa.id AND timestampdiff('SQL_TSI_DAY',wa.date,wen.date)>=0 AND wen.weight IS NOT NULL AND wen.date <= wa.date) + ) + ) AS InnerWeight, + (SELECT MAX(wen.date) + FROM study.weight wen + WHERE (wen.id=wa.id AND timestampdiff('SQL_TSI_DAY',wa.date,wen.date)>=0 AND wen.weight IS NOT NULL AND wa.date >= wen.date) + ) AS RecentWeight, + + --Showing latest mlsPerKg from Water Schedules Dataset + (SELECT wsa.mlsperKg + FROM study.waterScheduledAnimals wsa + WHERE wsa.id = wa.id AND wsa.date = ( + SELECT MAX(wsaDate.date) + FROM study.waterScheduledAnimals wsaDate + WHERE (wsaDate.id=wa.id AND wsaDate.mlsperKg IS NOT NULL AND wsaDate.date <= wa.date) + ) + ) AS InnerMlsPerKg, + (SELECT MAX(wsa.date) + FROM study.waterScheduledAnimals wsa + WHERE (wsa.id=wa.id AND wsa.mlsperKg IS NOT NULL AND wa.date >= wsa.date) + ) AS RecentMlsPerKg + + FROM study.waterGiven wa + WHERE wa.qcstate.label = 'Completed' + GROUP BY wa.id, wa.date + +) voGi +WHERE voGi.InnerWeight IS NOT NULL +--GROUP BY voGi.id,voGi.date,voGi.projectConcat,voGi.performedConcat,voGi.qcstateConcat,voGi.volumeGivenInLabSub,voGi.volumeGivenInCage,voGi.volumeGivenInImage,voGi.volumeGivenInProcedure,voGi.TotalWater,voGi.RecentWeight,voGi.InnerWeight,voGi.RecentMlsPerKg,voGi.InnerMlsPerKg +GROUP BY voGi.id,voGi.date,voGi.performedConcat,voGi.qcstateConcat,voGi.volumeGivenInLabSub,voGi.volumeGivenInCage,voGi.volumeGivenInImage,voGi.volumeGivenInProcedure,voGi.TotalWater,voGi.RecentWeight,voGi.InnerWeight,voGi.RecentMlsPerKg,voGi.InnerMlsPerKg +--voGi.Weight diff --git a/WNPRC_EHR/resources/queries/study/waterPrePivot/.qview.xml b/WNPRC_EHR/resources/queries/study/waterPrePivot/.qview.xml new file mode 100644 index 000000000..932a4d486 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterPrePivot/.qview.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterRemaining.sql b/WNPRC_EHR/resources/queries/study/waterRemaining.sql new file mode 100644 index 000000000..cd172b204 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterRemaining.sql @@ -0,0 +1,5 @@ +SELECT +*, +wg.id.dataset.activehousing.room as CurrentRoom, +wg.id.dataset.activehousing.cage as CurrentCage, +FROM waterGiven wg \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterSchedule.query.xml b/WNPRC_EHR/resources/queries/study/waterSchedule.query.xml new file mode 100644 index 000000000..f8446803f --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterSchedule.query.xml @@ -0,0 +1,184 @@ + + + + + /EHR/treatmentDetails.view?key=${lsid} + primaryKey + + + false + + + true + + + yyyy-MM-dd hh:mm + + + + study + animal + Id + + + + + ehr + project + project + + + + Treatment Start Date + yyyy-MM-dd + + + false + SNOMED Code + + ehr_lookups + snomed + code + + + + + + + + + + + false + + wnprc + husbandry_frequency + rowid + + + + 250 + + + 40 + + ehr_lookups + rooms + Room + + + + 40 + + + true + + + true + + study + qcstate + rowid + + + + + + + + + E3170D + + + + + Concentration + + + Amount Given + + + Volume + + + Volume + + + + false + true + Status + 50 + + study + qcstate + rowid + + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + false + Task Id + + ehr + tasks + taskid + + /ehr/taskDetails.view?formtype=${taskid/formtype}&taskid=${taskid} + + + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterSchedule.sql b/WNPRC_EHR/resources/queries/study/waterSchedule.sql new file mode 100644 index 000000000..24cd58ff8 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterSchedule.sql @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +SELECT +d.id AS animalId, +d.calculated_status, +s.*, +s.objectid as treatmentid, +--(SELECT max(d.qcstate) as label FROM study.drug d WHERE s.objectid = d.treatmentid AND s.date = d.timeordered) as treatmentStatus, +COALESCE((SELECT max(wg.qcstate) as label FROM study.waterGiven wg WHERE wg.treatmentid LIKE '%' || s.objectid || '%' AND s.date = wg.dateordered AND wg.volume IS NOT NULL ),10) as waterStatus, +--COALESCE((SELECT max(wg.qcstate) as label FROM study.waterGiven wg WHERE s.objectid IN (wg.treatmentid) AND s.date = wg.dateordered AND wg.volume IS NOT NULL ),10) as waterStatus, +COALESCE((SELECT max(wg.treatmentid) as treatmentIds FROM study.waterGiven wg WHERE s.date = wg.dateordered AND wg.volume IS NOT NULL ),'objectId') as watertreatment + + +FROM study.demographics d + +JOIN ( + SELECT + s.*, + timestampadd('SQL_TSI_MINUTE', ((s.hours * 60) + s.minutes ), s.origDate) as date, + CASE + WHEN (hours >= 6 AND hours < 12) THEN 'AM' + WHEN (hours < 20 OR hours >= 12) THEN 'PM' + ELSE 'Other' + END as timeOfDay, + + ((s.hours * 60) + s.minutes) as timeOffset + + FROM ( + + SELECT + + t1.objectid, + t1.taskid, + t1.lsid, + t1.dataset, + t1.id as wanimalid, + + COALESCE ( ft.hourofday, ((hour(t1.date) * 100) + minute(t1.date))) as time, + (coalesce( (ft.hourofday), (hour(t1.date) * 100)) / 100) as hours, + CASE + WHEN ( ft.hourofday IS NOT NULL) + THEN (((ft.hourofday / 100.0) - floor(ft.hourofday / 100)) * 100) + ELSE minute(t1.date) + END as minutes, + + dr.date as origDate, + t1.created AS created, + t1.id.curLocation.area as area, + t1.id.curLocation.room as room, + t1.id.curLocation.cage as cage, + dr.startDate AS dateRangeStartDate, + t1.date as startDate, + timestampdiff('SQL_TSI_DAY', cast(t1.dateOnly as timestamp), dr.dateOnly) + 1 as daysElapsed, + t1.enddate, + t1.enddateCoalescedFuture, --column use to display future dates when the endDate is null + t1.frequency AS frequency, + t1.frequency.meaning AS freqMeaning, + ft.timedescription AS displaytimeofday, + t1.provideFruit AS provideFruit, + t1.provideFruit.title AS provideFruitTitle, + t1.assignedTo, + t1.assignedTo.title AS assignedToTittle, + t1.waterSource, + t1.project, + t1.volume, + t1.qcstate + + FROM ehr_lookups.dateRange dr + + JOIN study.waterOrders t1 + --NOTE: should the enddate consider date/time? + ON dr.dateOnly >= t1.dateOnly AND dr.dateOnly <= t1.enddateCoalescedFuture + + LEFT JOIN ehr_lookups.treatment_frequency_times ft ON (ft.frequency = t1.frequency.meaning) + + INNER JOIN + wnprc.husbandry_frequency hf + -- Frequencies that are not daily, we used the dayofweek tp populate schedule + -- If daily it shows every day. + ON ( + ((hf.meaning = t1.frequency.meaning) + AND (t1.frequency.meaning LIKE 'Daily%') + ) + OR + ((hf.meaning = t1.frequency.meaning) + AND (t1.frequency.meaning NOT LIKE 'Daily%') + AND (dayofweek(dr.date) = hf.dayofweek) + ) + ) + + + --NOTE: if we run this report on a future interval, we want to include those treatments + WHERE t1.date is not null --AND QCState = '1' + + ) s + +) s ON (s.wanimalid = d.id) + +WHERE (d.lastDayatCenter Is Null OR d.lastDayAtCenter >= s.enddateCoalescedFuture) + +--Adding differet frequecies time + + +--account for date/time in schedule +--origDate has to have 00:00 a time otherwise it does not include the first day of the order +and s.origDate >= s.startDate and s.origDate <= s.enddateCoalescedFuture + +--Filtering water regulated +--AND (s.waterSource = 'regulated' OR s.startDate = s.origDate) \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced.query.xml b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced.query.xml new file mode 100644 index 000000000..897b9c54b --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced.query.xml @@ -0,0 +1,218 @@ + + + + + /EHR/treatmentDetails.view?key=${lsid} + primaryKey + + + true + true + + + true + true + + + true + + + true + + + yyyy-MM-dd HH:mm + + + yyyy-MM-dd HH:mm + + + + study + animal + Id + + + + + ehr + project + project + + + + Treatment Start Date + yyyy-MM-dd + + + false + SNOMED Code + + ehr_lookups + snomed + code + + + + + + + + + + + false + + wnprc + husbandry_frequency + rowid + + + + + ehr_lookups + husbandry_assigned + value + + + + + 250 + + + 40 + + ehr_lookups + rooms + Room + + + + 40 + + + true + + + Date Ordered + yyyy-MM-dd HH:mm:ss + + + true + + study + qcstate + rowid + + + + + + + + + E3170D + + + + + Volume + + + + ehr_lookups + water_source + value + title + + + + + ehr_lookups + husbandry_fruit + value + title + + + + + + + + + false + true + Status + 50 + + study + qcstate + rowid + + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + false + Task Id + + ehr + tasks + taskid + + /ehr/taskDetails.view?formtype=${taskid/formtype}&taskid=${taskid} + + + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced.sql b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced.sql new file mode 100644 index 000000000..0a743a2c2 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced.sql @@ -0,0 +1,73 @@ +-- UNION ALL faster query +-- water amount not matching time, need to add water amount according to the time set of the frequency +-- the date will match as it does with the water schedule. + +(SELECT + WA.id AS animalId, + WA.date AS date, + WA.date AS dateOrdered, + WA.id.curLocation.area as area, + WA.id.curLocation.room as room, + WA.id.curLocation.cage as cage, + WA.date AS startDateCoalesced, + WA.date AS endDateCoalescedFuture, + CAST (WA.volume AS DOUBLE) AS volume, + WA.assignedTo AS assignedTo, + WA.assignedTo.title AS assignedToTitle, + WA.provideFruit AS provideFruit, + WA.provideFruit.title AS provideFruitTitle, + 'waterAmount' AS dataSource, + WA.objectid AS objectid, + WA.taskid AS taskid, + WA.lsid AS lsid, + WA.project AS project, + WA.frequency AS frequency, + WA.frequency.meaning AS frequencyMeaning, + 'PM' AS timeofday, + 'PM' AS displaytimeofday, + WA.waterSource AS waterSource, + true AS actionRequired, + WA.qcstate AS qcstate + + +FROM study.waterAmount WA +--WHERE WA.date >= curdate() +) + +UNION ALL + +(SELECT + WS.animalId AS animalId, + WS.origDate AS origDate, + WS.date AS dateOrdered, + WS.area as area, + WS.room as room, + WS.cage as cage, + WS.startDate AS startDateCoalesced, + WS.enddateCoalescedFuture AS endDateCoalescedFuture, + CAST (WS.volume AS DOUBLE) AS volume, + WS.assignedTo AS assignedTo, + WS.assignedToTittle AS assignedToTitle, + WS.provideFruit AS provideFruit, + WS.provideFruitTitle AS provideFruitValue, + 'waterOrders' AS dataSource, + WS.objectid AS objectid, + WS.taskid AS taskid, + WS.lsid AS lsid, + WS.project AS project, + WS.frequency AS frequency, + WS.freqMeaning AS frequencyMeaning, + WS.timeOfDay AS timeofday, + WS.displaytimeofday AS displaytimeofday, + WS.waterSource AS waterSource, + (WS.waterSource = 'regulated' OR WS.startDate = WS.origDate) AS actionRequired, + WS.waterStatus AS qcstate + + +FROM study.waterSchedule WS +WHERE NOT EXISTS (SELECT 1 + FROM study.waterAmount WAI + WHERE WAI.id = WS.animalId AND CAST(WAI.date AS TIMESTAMP) = CAST(WS.date AS TIMESTAMP) + --AND WAI.frequency = WS.frequency + ) +) \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced/.qview.xml b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced/.qview.xml new file mode 100644 index 000000000..a8796b847 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced/.qview.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced/Scheduled.qview.xml b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced/Scheduled.qview.xml new file mode 100644 index 000000000..72fc42dcf --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterScheduleCoalesced/Scheduled.qview.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterScheduledAnimalWithOutEntries.sql b/WNPRC_EHR/resources/queries/study/waterScheduledAnimalWithOutEntries.sql new file mode 100644 index 000000000..0b71dfd1d --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterScheduledAnimalWithOutEntries.sql @@ -0,0 +1,10 @@ +PARAMETERS(CheckDate TIMESTAMP); + +SELECT DISTINCT(id), CheckDate AS date FROM + (SELECT a.id, a.MostRecentWaterCondition FROM study.demographicsMostRecentWaterCondition a + WHERE NOT EXISTS ( + SELECT 1 FROM study.waterPrePivot b + WHERE a.id = b.animalId AND b.date = CheckDate + ) + ) +WHERE MostRecentWaterCondition = 'regulated' \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/waterScheduledAnimals.query.xml b/WNPRC_EHR/resources/queries/study/waterScheduledAnimals.query.xml new file mode 100644 index 000000000..0772b55ee --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/waterScheduledAnimals.query.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + Start Date + yyyy-MM-dd + + + End Date + yyyy-MM-dd hh:mm + + + Condition + + ehr_lookups + water_source + value + title + + + +
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/wnprcFullHistory.query.xml b/WNPRC_EHR/resources/queries/study/wnprcFullHistory.query.xml new file mode 100644 index 000000000..e6bfdade4 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/wnprcFullHistory.query.xml @@ -0,0 +1,252 @@ + + + + + + lsid + + + true + false + ALWAYS_OFF + + + ALWAYS_OFF + http://cpas.labkey.com/Study#ParticipantId + /ehr/participantView.view?participantId=${id} + + + false + 350 + ALWAYS_OFF + urn:ehr.labkey.org/#Remark + + + false + 300 + ALWAYS_OFF + urn:ehr.labkey.org/#Descrption + + + End Date + urn:ehr.labkey.org/#EndDate + DateTime + + + DateTime + + + + ehr + project + project + + + + urn:ehr.labkey.org/#Project + + + Case Number + + + urn:ehr.labkey.org/#CaseId + + + true + ALWAYS_OFF + urn:ehr.labkey.org/#ParentId + + + urn:ehr.labkey.org/#Account + + + 100 + urn:ehr.labkey.org/#UserId + + + ALWAYS_OFF + urn:ehr.labkey.org/#TaskId + false + Task Id + + ehr + tasks + taskid + + /ehr/taskDetails.view?formtype=${taskid/formtype}&taskid=${taskid} + + + ALWAYS_OFF + urn:ehr.labkey.org/#RequestId + false + Request Id + + ehr + requests + requestid + + /ehr/requestDetails.view?formtype=${requestid/formtype}&requestid=${requestid} + + + urn:ehr.labkey.org/#RunId + + + urn:ehr.labkey.org/#FormSort + + + urn:ehr.labkey.org/#ObjectId + + + Performed By + urn:ehr.labkey.org/#PerformedBy + + + urn:ehr.labkey.org/#DateFinalized + + + urn:ehr.labkey.org/#DateRequested + + + ALWAYS_OFF + false + Problem + + study + Problem List + objectid + category + + + + false + true + Status + 50 + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + + FBEC5D + + + + + + FF0000 + + + + + + FBEC5D + + + + + + FBEC5D + + + + + true + + + true + + + true + DateTime + + + true + + + true + DateTime + + + true + + + + + false + + + false + + + + ehr.context + ehr/studyButtons.js + EHR.DatasetButtons.moreActionsHandler + + Grid Views + + + Reports + + + Charts + + + Insert + + + Insert New Row + + + + + + + + + Export + + + Print + + + Import Bulk Data + + + Delete + + +
+
+
+
\ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/wnprcFullHistory.sql b/WNPRC_EHR/resources/queries/study/wnprcFullHistory.sql new file mode 100644 index 000000000..85d762815 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/wnprcFullHistory.sql @@ -0,0 +1,28 @@ +SELECT Id, + date, + CAST (project AS VARCHAR) AS project, + DataSet.Label AS dataset, + DataSet.Name AS DataSetName, + remark, + description, + performedby, + qcstate, + taskid, + requestid +FROM study.studyData + +UNION ALL +SELECT + animalId AS Id, + date, + projectConcat AS project, + 'Water Given (Total)' AS dataset, + 'watertotal' AS DataSetName, + 'Sum of all water given for the day.' AS remark, + 'Total Water for the day equals: ' || TotalWater || 'ml' AS description, + performedConcat AS performedBy, + qcstate AS qcstate, + null AS taskid, + null AS requestid + +FROM study.waterPrePivot \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/wnprcFullHistory/.qview.xml b/WNPRC_EHR/resources/queries/study/wnprcFullHistory/.qview.xml new file mode 100644 index 000000000..7b1e63236 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/wnprcFullHistory/.qview.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/study/wnprcFullHistory/Full History.qview.xml b/WNPRC_EHR/resources/queries/study/wnprcFullHistory/Full History.qview.xml new file mode 100644 index 000000000..85b6ffc46 --- /dev/null +++ b/WNPRC_EHR/resources/queries/study/wnprcFullHistory/Full History.qview.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WNPRC_EHR/resources/queries/wnprc/animal_requests.js b/WNPRC_EHR/resources/queries/wnprc/animal_requests.js index d843e63e2..42688aac4 100644 --- a/WNPRC_EHR/resources/queries/wnprc/animal_requests.js +++ b/WNPRC_EHR/resources/queries/wnprc/animal_requests.js @@ -62,7 +62,6 @@ function onUpsert(helper, scriptErrors, row, oldRow){ }); } row.animalidstooffer = subjectArray.join(";"); - } function onAfterInsert(helper,errors,row){ @@ -72,3 +71,9 @@ function onAfterInsert(helper,errors,row){ WNPRC.Utils.getJavaHelper().sendAnimalRequestNotification(rowid, hostName); } +function onAfterUpdate(helper,errors,row,oldRow){ + var rowid = row.rowId; + var hostName = 'https://' + LABKEY.serverName; + console.log ("animal_requests.js: New request updated, rowid: "+ rowid); + WNPRC.Utils.getJavaHelper().sendAnimalRequestNotificationUpdate(rowid, row, oldRow, hostName); +} diff --git a/WNPRC_EHR/resources/queries/wnprc/animal_requests.query.xml b/WNPRC_EHR/resources/queries/wnprc/animal_requests.query.xml index ba01e87a9..1625c5465 100644 --- a/WNPRC_EHR/resources/queries/wnprc/animal_requests.query.xml +++ b/WNPRC_EHR/resources/queries/wnprc/animal_requests.query.xml @@ -3,14 +3,24 @@ Animal Requests - + + + + + Edit + + + # + + Date Requested yyyy-MM-dd hh:mm + false - Create By + Created By Principal Investigator @@ -25,11 +35,11 @@ # of Animals - Species + Species Needed ehr_lookups animal_requests_species - value + common Species @@ -71,8 +81,7 @@ Disposition ehr_lookups animal_requests_disposition - meaning - Origin + value @@ -132,6 +141,9 @@ Animal Origin + + Animal History + diff --git a/WNPRC_EHR/resources/queries/wnprc/animal_requests/Animal Requests.qview.xml b/WNPRC_EHR/resources/queries/wnprc/animal_requests/Animal Requests.qview.xml index 6e6d66661..a4487b73d 100644 --- a/WNPRC_EHR/resources/queries/wnprc/animal_requests/Animal Requests.qview.xml +++ b/WNPRC_EHR/resources/queries/wnprc/animal_requests/Animal Requests.qview.xml @@ -1,6 +1,7 @@ - + + @@ -10,6 +11,8 @@ + + diff --git a/WNPRC_EHR/resources/queries/wnprc/watermonitoring_access.query.xml b/WNPRC_EHR/resources/queries/wnprc/watermonitoring_access.query.xml new file mode 100644 index 000000000..f3d3be116 --- /dev/null +++ b/WNPRC_EHR/resources/queries/wnprc/watermonitoring_access.query.xml @@ -0,0 +1,43 @@ + + + +
+ Water Monitoring Access + + + + Date + yyyy-MM-dd + + + Allowed User + + core + PrincipalsWithoutAdmin + UserId + + + + + ehr + project + project + + + + Create By + + + Principal Investigator + + ehr + uniqueProtocolInvestigator + inves + inves + + + +
+
+ + \ No newline at end of file diff --git a/WNPRC_EHR/resources/referenceStudy/datasets/datasets_manifest.xml b/WNPRC_EHR/resources/referenceStudy/datasets/datasets_manifest.xml index f1aff28d5..e5e859a95 100644 --- a/WNPRC_EHR/resources/referenceStudy/datasets/datasets_manifest.xml +++ b/WNPRC_EHR/resources/referenceStudy/datasets/datasets_manifest.xml @@ -69,5 +69,12 @@ + + + + + + + diff --git a/WNPRC_EHR/resources/referenceStudy/datasets/datasets_metadata.xml b/WNPRC_EHR/resources/referenceStudy/datasets/datasets_metadata.xml index 0ebc1eab0..aa3586cb9 100644 --- a/WNPRC_EHR/resources/referenceStudy/datasets/datasets_metadata.xml +++ b/WNPRC_EHR/resources/referenceStudy/datasets/datasets_metadata.xml @@ -7562,4 +7562,239 @@
+ + + + entityid + Key + urn:ehr.labkey.org/#ObjectId + true + true + + + varchar + Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + study + Animal + Id + + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + false + + + integer + Project + urn:ehr.labkey.org/#Project + + pno + + 00000000 + + + timestamp + Enddate + urn:ehr.labkey.org/#EndDate + true + + +
+ + + + entityid + Key + urn:ehr.labkey.org/#ObjectId + true + true + + + varchar + Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + study + Animal + Id + + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + false + + + integer + Project + urn:ehr.labkey.org/#Project + + pno + + 00000000 + + +
+ + + + entityid + Key + urn:ehr.labkey.org/#ObjectId + true + true + + + varchar + Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + study + Animal + Id + + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + false + + + integer + Project + urn:ehr.labkey.org/#Project + + pno + + 00000000 + + +
+ + + + entityid + Key + urn:ehr.labkey.org/#ObjectId + true + true + + + varchar + Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + study + Animal + Id + + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + false + + + integer + Project + urn:ehr.labkey.org/#Project + + pno + + 00000000 + + + +
+ + + + entityid + Key + urn:ehr.labkey.org/#ObjectId + true + true + + + varchar + Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + study + Animal + Id + + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + false + + + integer + Project + urn:ehr.labkey.org/#Project + + pno + + 00000000 + + +
+ + + + entityid + Key + urn:ehr.labkey.org/#ObjectId + true + true + + + varchar + Id + Subject identifier + http://cpas.labkey.com/Study#ParticipantId + false + + study + Animal + Id + + + + timestamp + Date + http://cpas.labkey.com/Study#VisitDate + false + + + integer + Project + urn:ehr.labkey.org/#Project + + pno + + 00000000 + + +
diff --git a/WNPRC_EHR/resources/schemas/dbscripts/postgresql/wnprc-21.000-21.001.sql b/WNPRC_EHR/resources/schemas/dbscripts/postgresql/wnprc-21.000-21.001.sql new file mode 100644 index 000000000..9d6828e92 --- /dev/null +++ b/WNPRC_EHR/resources/schemas/dbscripts/postgresql/wnprc-21.000-21.001.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS ehr_lookups.husbandry_frequency; + +CREATE TABLE wnprc.husbandry_frequency +( + RowId serial NOT NULL, + meaning varchar(100) DEFAULT NULL NOT NULL, + dayofweek integer, + sort_order integer, + active bool DEFAULT true, + altmeaning varchar(30), + CONSTRAINT PK_husbandry_frequency PRIMARY KEY (rowid) +) + WITH (OIDS= FALSE); + +INSERT INTO wnprc.husbandry_frequency +(rowid, meaning,dayofweek, sort_order,active,altmeaning) +VALUES +(1, 'Daily - AM', NULL, 1,'TRUE', 'AM'), +(2, 'Daily - PM', NULL, 2,'TRUE','PM'), +(3, 'Daily - AM/PM', NULL, 3,'TRUE',''), +(4, 'Daily - Any Time', NULL, 4,'TRUE','Any Time'), +(5, 'Sunday', '1', 5,'TRUE',''), +(6, 'Monday', '2', 6,'TRUE',''), +(7, 'Tuesday', '3', 7,'TRUE',''), +(8, 'Wednesday', '4', 8,'TRUE',''), +(9, 'Thursday', '5', 9,'TRUE',''), +(10, 'Friday', '6', 10,'TRUE',''), +(11, 'Saturday', '7', 11,'TRUE',''); diff --git a/WNPRC_EHR/resources/schemas/wnprc.xml b/WNPRC_EHR/resources/schemas/wnprc.xml index 643e83063..1f192e15b 100644 --- a/WNPRC_EHR/resources/schemas/wnprc.xml +++ b/WNPRC_EHR/resources/schemas/wnprc.xml @@ -240,5 +240,14 @@ - + + + + + + + + + +
diff --git a/WNPRC_EHR/resources/views/dataEntry.html b/WNPRC_EHR/resources/views/dataEntry.html index 6578fbcd0..a2c280edf 100644 --- a/WNPRC_EHR/resources/views/dataEntry.html +++ b/WNPRC_EHR/resources/views/dataEntry.html @@ -1,722 +1,736 @@ - + diff --git a/WNPRC_EHR/resources/views/ehrAdmin.html b/WNPRC_EHR/resources/views/ehrAdmin.html index 627367320..6ae02c196 100644 --- a/WNPRC_EHR/resources/views/ehrAdmin.html +++ b/WNPRC_EHR/resources/views/ehrAdmin.html @@ -108,4 +108,4 @@ }); - + \ No newline at end of file diff --git a/WNPRC_EHR/resources/views/ehrBegin.html b/WNPRC_EHR/resources/views/ehrBegin.html index e629ec7fe..51de9d77e 100644 --- a/WNPRC_EHR/resources/views/ehrBegin.html +++ b/WNPRC_EHR/resources/views/ehrBegin.html @@ -84,6 +84,7 @@ {name: 'Colony Census', url: '<%=contextPath%>/wnprc_ehr' + ctx['EHRStudyContainer'] + '/colonyCensus.view?'}, {name: 'Pregnancies', url: '<%=contextPath%>/wnprc_ehr' + ctx['EHRStudyContainer'] + '/breeding.view?'}, {name: 'Research Ultrasounds', url: '<%=contextPath%>/wnprc_ehr' + ctx['EHRStudyContainer'] + '/research_ultrasounds.view?'}, + {name: 'Water Calendar', url: '<%=contextPath%>/wnprc_ehr' + ctx['EHRStudyContainer'] + '/watercalendar.view?'}, {name: 'Room Utilization', url: '<%=contextPath%>/query' + ctx['EHRStudyContainer'] + '/executeQuery.view?schemaName=ehr_lookups&query.queryName=roomUtilization'}, {name: 'Feeding', url: '<%=contextPath%>/query' + ctx['EHRStudyContainer'] + '/executeQuery.view?schemaName=study&query.queryName=feeding'}, {name: 'Time Chart', url: '<%=contextPath%>/visualization' + ctx['EHRStudyContainer'] + '/timeChartWizard.view?edit=true'}, diff --git a/WNPRC_EHR/resources/views/wnprcUnits.html b/WNPRC_EHR/resources/views/wnprcUnits.html index 8a16a2b9b..418375ef0 100644 --- a/WNPRC_EHR/resources/views/wnprcUnits.html +++ b/WNPRC_EHR/resources/views/wnprcUnits.html @@ -20,7 +20,8 @@ {header: 'Colony Management', items: [ {name: 'Issue Tracker', url: '<%=contextPath%>/project/WNPRC/WNPRC_Units/Animal_Services/Colony_Management/Issue_Tracker/start.view?'}, - {name: 'Colony Mgmt Staff Only**', url: '<%=contextPath%>/project/WNPRC/WNPRC_Units/Animal_Services/Colony_Management/begin.view?'} + {name: 'Colony Mgmt Staff Only**', url: '<%=contextPath%>/project/WNPRC/WNPRC_Units/Animal_Services/Colony_Management/begin.view?'}, + {name: 'Water Calendar', url: LABKEY.ActionURL.buildURL('wnprc_ehr', 'WaterCalendar', 'WNPRC/EHR')}, ]}, {header: 'Colony Records', items: [ @@ -99,9 +100,7 @@ ]}, {header: 'Purchasing Services', items: [ - {name: 'Purchasing Requests', url: '<%=contextPath%>/WNPRC/WNPRC_Units/Operation_Services/WNPRC Purchasing/WNPRC_Purchasing-requester.view?'}, - {name: 'Purchasing Admin', url: '<%=contextPath%>/WNPRC/WNPRC_Units/Operation_Services/WNPRC Purchasing/WNPRC_Purchasing-purchaseAdmin.view?'}, - {name: 'Purchasing Receiver', url: '<%=contextPath%>/WNPRC/WNPRC_Units/Operation_Services/WNPRC Purchasing/WNPRC_Purchasing-purchaseReceiver.view?'} + {name: 'Issue Tracker', url: '<%=contextPath%>/project/WNPRC/WNPRC_Units/Operation_Services/Purchasing/Issue_Tracker/start.view?'} ]} ] }); diff --git a/WNPRC_EHR/resources/web/ehr/ext3/ehrMetaHelper.js b/WNPRC_EHR/resources/web/ehr/ext3/ehrMetaHelper.js index f7456ab5e..815199294 100644 --- a/WNPRC_EHR/resources/web/ehr/ext3/ehrMetaHelper.js +++ b/WNPRC_EHR/resources/web/ehr/ext3/ehrMetaHelper.js @@ -386,6 +386,10 @@ EHR.ext.metaHelper = new function(){ if(meta.getRenderer) col.renderer = meta.getRenderer(col, meta, grid); + if (meta.css){ + col.css = meta.css; + } + col.renderer = EHR.ext.metaHelper.getDefaultRenderer(col, meta, col.renderer, grid); //HTML-encode the column header diff --git a/WNPRC_EHR/resources/web/ehr/metadata/Metadata.js b/WNPRC_EHR/resources/web/ehr/metadata/Metadata.js index 69a57b8e9..cc5a11fa3 100644 --- a/WNPRC_EHR/resources/web/ehr/metadata/Metadata.js +++ b/WNPRC_EHR/resources/web/ehr/metadata/Metadata.js @@ -237,7 +237,7 @@ EHR.Metadata.Columns = { Assignment: EHR.Metadata.topCols + ',projectedRelease,' + EHR.Metadata.bottomCols, 'Bacteriology Results': EHR.Metadata.topCols + ',method,organism,source,qualresult,result,units,antibiotic,sensitivity,performing_lab,' + EHR.Metadata.bottomCols, 'Behavior Remarks': EHR.Metadata.topCols + ',so,a,p,category,' + EHR.Metadata.bottomCols, - Biopsies: EHR.Metadata.topCols + ',caseno,type,veterinarian,performedby,nhpbmd,grossdescription,histologicalDescription,' + EHR.Metadata.bottomCols + ',patho_notes', + Biopsies: EHR.Metadata.topCols + ',billingComplete,caseno,type,veterinarian,performedby,nhpbmd,grossdescription,histologicalDescription,' + EHR.Metadata.bottomCols + ',patho_notes', Birth: EHR.Metadata.topCols + ',estimated,gender,weight,wdate,dam,sire,room,cage,cond,origin,ancestry,conception,type,' + EHR.Metadata.bottomCols, blood: 'id/curlocation/location,' + EHR.Metadata.topCols + ',objectid,requestid,tube_type,tube_vol,num_tubes,quantity,requestor,additionalServices,billedby,assayCode,restraint,restraintDuration,daterequested,instructions,' + EHR.Metadata.bottomCols, 'Body Condition': EHR.Metadata.topCols + ',score,weightstatus,remark,tattoo_chest,tattoo_thigh,microchip,tag,tattoo_remark,' + EHR.Metadata.bottomCols, diff --git a/WNPRC_EHR/resources/web/ehr/metadata/Task.js b/WNPRC_EHR/resources/web/ehr/metadata/Task.js index 847400547..8b20de425 100644 --- a/WNPRC_EHR/resources/web/ehr/metadata/Task.js +++ b/WNPRC_EHR/resources/web/ehr/metadata/Task.js @@ -32,7 +32,15 @@ EHR.Metadata.registerMetadata('Task', { ,'blood': { requestor:{xtype: 'displayfield'}, performedby: {allowBlank: false}, - billedby: {allowBlank: false}, + billedby: { + allowBlank: false, + lookup: { + schemaName: 'ehr_lookups', + queryName: 'blood_billed_by', + keyColumn: 'value', + displayColumn: 'description' + } + }, tube_type: {allowBlank: false}, daterequested: { hidden: false, diff --git a/WNPRC_EHR/resources/web/ehr/metadata/Treatments.js b/WNPRC_EHR/resources/web/ehr/metadata/Treatments.js index 6d226572e..c2a4235ca 100644 --- a/WNPRC_EHR/resources/web/ehr/metadata/Treatments.js +++ b/WNPRC_EHR/resources/web/ehr/metadata/Treatments.js @@ -18,16 +18,37 @@ EHR.Metadata.registerMetadata('Treatments', { }, colModel: { width: 120 - } + }, + css: 'border-left: solid 2px #000000;' }, volume: { + header: 'Vol', colModel: { - width: 50 - } + width: 40 + }, + css : 'font-weight:bold;' }, vol_units: { + header: 'VolUnits', colModel: { width: 50 + }, + css: 'font-weight:bold; border-right: solid 2px #000000;' + }, + concentration:{ + header: 'Conc', + shownInGrid: true, + compositeField: 'Drug Conc', + colModel: { + width: 45 + } + }, + conc_units:{ + header: 'ConcUnits', + shownInGrid: true, + compositeField: 'Drug Conc', + colModel: { + width: 60 } }, performedby: { @@ -47,7 +68,10 @@ EHR.Metadata.registerMetadata('Treatments', { } }, route: { - shownInGrid: true + shownInGrid: true, + colModel: { + width: 50 + } } } } diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/animalWaterCalendar.js b/WNPRC_EHR/resources/web/wnprc_ehr/animalWaterCalendar.js new file mode 100644 index 000000000..ee0060586 --- /dev/null +++ b/WNPRC_EHR/resources/web/wnprc_ehr/animalWaterCalendar.js @@ -0,0 +1,93 @@ +Ext4.namespace('EHR.Reports'); +let calendarRender = 0; +let entireColony = false; + +EHR.reports.animalWaterCalendar = function (panel, tab){ + + var animalIds = []; + //debugger; + if (tab.filters.subjects){ + // tab.filters.subjects.forEach (animalId => animalIds+=animalId+';'); + // animalIds = animalIds.substring(0, animalIds.length-1); + animalIds = tab.filters.subjects; + renderCalendar (animalIds, tab); + calendarRender++; + } if (panel.getFilterArray(tab).nonRemovable.length === 0){ + entireColony = true; + panel.resolveSubjectsFromHousing(tab,renderCalendar,this); + //renderCalendar('null', tab) + } + else{ + panel.resolveSubjectsFromHousing(tab,renderCalendar,this); + + } + + + + function renderCalendar(animalIds, tab){ + if (!animalIds.length){ + tab.add({ + html: 'No animal selected or found with water restrictions', + border: false + }) + } + var concatAnimals = ""; + + if (animalIds.length > 0){ + animalIds.forEach (animalId => concatAnimals+=animalId+';'); + concatAnimals = concatAnimals.substring(0, concatAnimals.length-1); + tab.add({ + xtype: 'panel', + id: 'waterCal' + + }) + + // Find the element to manipulate + var parentId = tab.getEl().id; + var child = Ext4.get(parentId + '-innerCt'); + + //TODO: not remove child everytime + // Remove any old tab content from previous animal selections + var childToRemove = child.down('.labkeyWaterMonitoringDiv'); + if (childToRemove) { + Ext4.destroy(childToRemove); + } + + // Inject a div to render into + var targetElement = child.createChild({tag: 'div'}); + targetElement.addCls('labkeyWaterMonitoringDiv'); + var id = Ext4.id(targetElement, "waterMonitoring"); + + let objectConfig ={} + if(!entireColony){ + objectConfig = {animalIds : concatAnimals,numberOfRenders: calendarRender,unbindComponents:'waterInfoPanel,calendarLegend,waterExceptionPanel'}; + + }else if(entireColony){ + objectConfig = {animalIds : 'null',numberOfRenders: calendarRender,unbindComponents:'waterInfoPanel,calendarLegend,waterExceptionPanel'}; + } + // Render the web part to the div + //TODO: add condition to check to request webpart only the first time + + var waterCalendar = new LABKEY.WebPart({ + partName: 'Water Calendar', + renderTo: id, + //partConfig: {animalIds : concatAnimals,numberOfRenders: calendarRender} + partConfig: objectConfig, + supressRenderErrors: true + }); + + + waterCalendar.render(); + + // We know the height of the component, so just set it explicitly instead of making ExtJS get the layout + // and sizing correct + tab.setHeight(1000); + } + + + } + + console.log ("new render"); + //animalIds.forEach(id => console.log (id)); + +} diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/data/HusbandryClientStore.js b/WNPRC_EHR/resources/web/wnprc_ehr/data/HusbandryClientStore.js new file mode 100644 index 000000000..79d9da9d0 --- /dev/null +++ b/WNPRC_EHR/resources/web/wnprc_ehr/data/HusbandryClientStore.js @@ -0,0 +1,35 @@ +Ext4.define('EHR.data.HusbandryClientStore', { + extend: 'EHR.data.DataEntryClientStore', + + constructor: function(){ + this.callParent(arguments); + }, + + getExtraContext: function(){ + var frequencyLabel = {}; + var allRecords = this.getRange(); + for (var idx = 0; idx < allRecords.length; ++idx){ + + var record = allRecords[idx]; + var id = record.get('Id'); + var label = record.get('frequency/meaning'); + + + + frequencyLabel[id].push({ + Id : id, + label: label + }) + } + + if (!LABKEY.Utils.isEmptyObj(frequencyLabel)){ + map = Ext4.encode(frequencyLabel); + + return { + frequencyLabels : frequencyLabel + } + } + return null; + } + +}); \ No newline at end of file diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/data/HusbandryServerStore.js b/WNPRC_EHR/resources/web/wnprc_ehr/data/HusbandryServerStore.js new file mode 100644 index 000000000..16013da03 --- /dev/null +++ b/WNPRC_EHR/resources/web/wnprc_ehr/data/HusbandryServerStore.js @@ -0,0 +1,110 @@ +Ext4.define('wnprc.ext.data.HusbandryServerStore', { + extend: 'EHR.data.DataEntryServerStore', + //alias: 'store.wnprc-HusbandryServerStore', + + constructor: function(){ + this.callParent(arguments); + + }, + + getCommands: function(records, forceUpdate, validateOnly){ + var commands = []; + var recordsPerCommand = []; + + //batch records into CRUD operations + var recMap = { + create: [], + update: [], + destroy: [] + }; + + //only commit changed records + if (!records){ + recMap.create = this.getNewRecords() || []; + recMap.update = this.getUpdatedRecords() || []; + + if (!validateOnly){ + var removed = this.getRemovedRecordsToSync(); + if (removed.destroy.length) + recMap.destroy = removed.destroy; + if (removed.update.length) + recMap.update = recMap.update.concat(removed.update); + } + } + else { + var r; + for (var i=0; i 0){ + var id = record.get('Id'); + var date = record.get('date'); + if (!id || !date) + continue; + + date = date.format(LABKEY.extDefaultDateFormat); + + if (!waterMap[id]) + waterMap[id] = []; + + waterMap[id].push({ + objectid: record.get('objectid'), + treatmentId: record.get('treatmentId'), + date: date, + qcstate: record.get('qcstate'), + volume: record.get('volume'), + assignedto: record.get('assignedto'), + datasource: record.raw.dataSource, + //remove waterobjects and use treamentIds to complete + waterObjects: record.raw.waterObjects + }); + } + } + + if (!LABKEY.Utils.isEmptyObj(waterMap)){ + waterMap = Ext4.encode(waterMap); + + return { + waterInTransaction: waterMap + } + } + + return extraContent; + + + } + + +}); \ No newline at end of file diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/ext4/data/SingleAnimal/WaterServerStore.js b/WNPRC_EHR/resources/web/wnprc_ehr/ext4/data/SingleAnimal/WaterServerStore.js new file mode 100644 index 000000000..40a3692fc --- /dev/null +++ b/WNPRC_EHR/resources/web/wnprc_ehr/ext4/data/SingleAnimal/WaterServerStore.js @@ -0,0 +1,176 @@ +Ext4.define('WNPRC.ext.data.WaterServerStore', { + extend: 'EHR.data.DataEntryServerStore', + alias: 'store.wnprc-waterserverstore', + + constructor: function(){ + this.callParent(arguments); + }, + + getCommands: function(records, forceUpdate, validateOnly){ + var commands = []; + var recordsPerCommand = []; + + //batch records into CRUD operations + var recMap = { + create: [], + update: [], + destroy: [] + }; + + //only commit changed records + if (!records){ + recMap.create = this.getNewRecords() || []; + recMap.update = this.getUpdatedRecords() || []; + + if (!validateOnly){ + var removed = this.getRemovedRecordsToSync(); + if (removed.destroy.length) + recMap.destroy = removed.destroy; + if (removed.update.length) + recMap.update = recMap.update.concat(removed.update); + } + } + else { + var r; + for (var i=0; i 0){ + this.addSubjects(subjectList, curDate, assignedTo, frequency) + } + else { + Ext4.Msg.alert('Error', 'Must enter at least 1 animal Id'); + } + } + }, + + loadWater: function(results){ + if (!results || !results.rows || !results.rows.length){ + Ext4.Msg.hide(); + Ext4.Msg.alert('', 'No scheduled water schedule were found.'); + return; + } + + // var targetStore = this.dataEntryPanel.storeCollection.getClientStoreByName('Water Given'); + //LDK.Assert.asserNotEmpty('Unable to find targetStore in AddScheduleWaterWindow', targetStore); + + //LDK.Assert.assertNotEmpty('Unable to find targetStore in AddScheduledTreatmentsWindow', this.targetStore); + + var records = []; + let waterRecord = new Map(); + let waterObjects = {}; + let matchingDate = ''; + let dataSource = ''; + let containsWaterOrder = new Boolean(false); + let containsWaterAmount = new Boolean(false); + //var performedby = this.down('#performedBy').getValue(); + + + Ext4.Array.each(results.rows, function(sr){ + var row = new LDK.SelectRowsRow(sr); + let animalId = row.getValue('animalid'); + var dateCurrentTime = new Date(); + var modelDate = new Date (row.getValue('date')); + modelDate.setHours(dateCurrentTime.getHours()); + modelDate.setMinutes(dateCurrentTime.getMinutes()); + + let waterObject = {treatmentId: row.getValue('objectid'), volume: row.getValue('volume'), assignedTo: row.getValue('assignedTo'), + dataSource: row.getValue('dataSource'), lsid:row.getValue('lsid')}; + + let previousVolume = 0; + let previousTreatmentId = ''; + let previousDataSource = ''; + + + + if (!containsWaterOrder){ + matchingDate = new Date(modelDate); + + } + + if (waterRecord.has(animalId) && waterRecord.get(animalId).raw.model == 'waterRecord'){ + previousVolume = waterRecord.get(animalId).get('volume'); + previousTreatmentId = ';' + waterRecord.get(animalId).get('treatmentId'); + previousDataSource = ';' + waterRecord.get(animalId).get('dataSource'); + //waterObjects.push({treatmentId:waterRecord.get(animalId).get('treatmentId'), volume: waterRecord.get(animalId).get('volume')}); + //waterObjects[animalId].push(waterObject); + } + + if (!waterObjects[animalId]){ + waterObjects[animalId] = []; + } + + if (row.getValue('dataSource') == 'waterOrders' ){ + + /*if ( dataSource != 'atLeastAWaterAmount'){ + dataSource = row.getValue('dataSource'); + }*/ + //for water Orders I need to keep the date ordered from the waterschedule to change qc state + matchingDate = row.getValue('dateOrdered'); + containsWaterOrder = true; + } + + waterObjects[animalId].push(waterObject); + + var tempModel = this.targetStore.createModel({ + Id: row.getValue('animalid'), + date: modelDate, + volume: row.getValue('volume') + previousVolume, + project: row.getValue('project'), + assignedto: row.getValue('assignedTo'), + waterSource: row.getValue('waterSource'), + treatmentId: row.getValue('objectid') + previousTreatmentId, + dataSource: row.getValue('dataSource') + previousDataSource, + dateOrdered: matchingDate, + model: 'waterRecord', + waterObjects: waterObjects[animalId] + + + }); + + tempModel.phantom = false; + waterRecord.set(animalId,tempModel); + + if ( row.getValue('provideFruit') != 'none' && row.getValue('provideFruit') != null){ + var fruitModel = this.targetStore.createModel({ + Id: row.getValue('animalid'), + date: modelDate, + provideFruit: row.getValue('provideFruit'), + project: row.getValue('project'), + assignedto: row.getValue('assignedTo'), + waterSource: row.getValue('waterSource'), + treatmentId: row.getValue('objectid'), + dataSource: row.getValue('dataSource'), + dateOrdered: row.getValue('dateOrdered'), + model: 'fruitRecord' + + }); + fruitModel.phantom = false; + waterRecord.set(animalId+'fruit',fruitModel); + + } + + + + }, this); + + waterRecord.forEach(function (value,key) { + records.push(value); + }) + + this.targetStore.add(records); + Ext4.Msg.hide(); + }, + + locationHandler: function(){ + var form = this.down('#theForm'); + form.removeAll(); + form.add([{ + html: 'This will return any animals currently housed in the selected location. You can leave any of the fields blank.', + style: 'padding-bottom: 10px;' + },{ + xtype: 'ehr-areafield', + multiSelect: false, + emptyText: '', + fieldLabel: 'Area', + itemId: 'areaField', + pairedWithRoomField: true, + getRoomField: function(){ + return this.up('form').down('#roomField') + } + },{ + xtype: 'ehr-roomfield', + multiSelect: true, + emptyText: '', + showOccupiedOnly: true, + fieldLabel: 'Room(s)', + itemId: 'roomField', + listeners: { + change: function(field){ + var areaField = field.up('panel').down('#areaField'); + areaField.reset(); + } + } + },{ + xtype: 'ehr-cagefield', + itemId: 'cageField', + fieldLabel: 'Cage(s)' + }]); + + form.getAnimals = function(){ + var room = this.down('#roomField').getValue(); + room = !room || Ext4.isArray(room) ? room : [room]; + + var cage = this.down('#cageField').getValue(); + if (cage){ + cage = cage.split(','); + var cages = []; + Ext4.Array.forEach(cage, function(c){ + cages.push(Ext4.String.trim(c)); + }, this); + cage = cages.join(';'); + } + + var filterArray = this.getBaseFilterArray().concat([LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL)]); + + if (!Ext4.isEmpty(room)) + filterArray.push(LABKEY.Filter.create('room', room.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); + + if (!Ext4.isEmpty(cage)) + filterArray.push(LABKEY.Filter.create('cage', cage, LABKEY.Filter.Types.EQUALS_ONE_OF)); + + if (filterArray.length == 1){ + Ext4.Msg.alert('Error', 'Must choose a location'); + return; + } + + this.doQuery({ + schemaName: 'study', + queryName: 'housing', + sort: 'room,cage,Id', + filterArray: filterArray + }); + } + }, + + /** + * Can be overridden by subclasses, for example to return only females + */ + getBaseFilterArray: function(){ + return []; + }, + + + + getAnimals: function(){ + let animalIds = this.down('#theForm').getAnimals.call(this); + + + + }, + + + doQuery: function(config){ + this.hide(); + Ext4.Msg.wait("Loading..."); + + //find distinct animals matching criteria + LABKEY.Query.selectRows(Ext4.applyIf(config, { + sort: 'Id', + columns: 'Id,Id/curLocation/location', + scope: this, + success: this.onSuccess, + failure: LDK.Utils.getErrorCallback() + })); + }, + + onSuccess: function(results){ + if (!results.rows || !results.rows.length){ + Ext4.Msg.hide(); + Ext4.Msg.alert('', 'No matching animals were found.'); + return; + } + + var records = []; + var hasLocation = this.targetStore.getFields().get('Id/curLocation/location'); + Ext4.Array.forEach(results.rows, function(row){ + if(row.Id){ + var startDate = this.down('#StartDate').getValue(); + var endDate = this.down('#EndDate').getValue(); + var numberOfDays = moment.subtract(endDate,startDate).days(); + + var obj = { + Id: row.Id + }; + + if (hasLocation){ + obj['Id/curLocation/location'] = row['Id/curLocation/location']; + } + + //for () + + records.push(obj); + } + }, this); + + this.addSubjects(records); + } +}); + +EHR.DataEntryUtils.registerGridButton('ADDSCHEDULEDWATERS', function(config){ + return Ext4.Object.merge({ + text: 'Add Scheduled Waters', + tooltip: 'Click to add animals by location', + handler: function(btn){ + var grid = btn.up('gridpanel'); + + Ext4.create('wnprc_ehr.window.AddScheduledWaterWindow', { + dataEntryPanel: grid, + targetStore: grid.store, + formConfig: grid.formConfig + }).show(); + } + }, config); +}); \ No newline at end of file diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddScheduledFoodDeprivesWindow.js b/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddScheduledFoodDeprivesWindow.js index 5e8a6e573..94b9b8bb8 100644 --- a/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddScheduledFoodDeprivesWindow.js +++ b/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddScheduledFoodDeprivesWindow.js @@ -71,7 +71,7 @@ Ext4.define('EHR.window.AddScheduledFoodDeprivesWindow', { fieldLabel: 'Assigned To', itemId: 'assignedto', displayField: 'title', - valueField: 'title', + valueField: 'value', defaultListConfig: {loadingHeight: 70, minHeight: 95, maxHeight: 600, shadow: 'sides'}, store: { type: 'labkey-store', diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddWaterWindow.js b/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddWaterWindow.js new file mode 100644 index 000000000..9a98e86ff --- /dev/null +++ b/WNPRC_EHR/resources/web/wnprc_ehr/ext4/windows/AddWaterWindow.js @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2013-2015 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @class + * This is the panel that appears when hitting the 'Add Bulk' button on EHR grids. It provides a popup to find the set of + * distinct animal IDs based on room, case, etc. + * + * @cfg targetStore + * @cfg formConfig + */ +Ext4.define('EHR.window.AddWaterWindow', { + extend: 'Ext.window.Window', + + MAX_ANIMALS: 350, + + initComponent: function(){ + Ext4.apply(this, { + title: 'Choose Animals', + modal: true, + closeAction: 'destroy', + border: true, + bodyStyle: 'padding:5px', + width: 450, + defaults: { + width: 400, + labelWidth: 140, + border: false, + bodyBorder: false + }, + items: [{ + html: 'This helper is designed to quickly add records to the grid below. You can look up animals in a variety of different ways. For each animal, one record will be created. If you check the \'Bulk Edit\' box, you will be prompted to fill out values for the other fields. If not, one row will be created per animal with blank values.', + style: 'padding-bottom: 10px;' + },{ + xtype: 'radiogroup', + itemId: 'radio', + fieldLabel: 'Choose Type', + columns: 1, + defaults: { + xtype: 'radio', + name: 'type' + }, + items: [{ + inputValue: 'animal', + boxLabel: 'List of Animals', + checked: true + },{ + inputValue: 'location', + boxLabel: 'Location' + },{ + inputValue: 'animalGroup', + boxLabel: 'Animal Group' + },{ + inputValue: 'project', + boxLabel: 'Project/Protocol' + }], + listeners: { + scope: this, + change: this.onTypeChange + } + },{ + xtype: 'checkbox', + fieldLabel: 'Bulk Edit Values', + helpPopup: 'If checked, you will be prompted with a screen that lets you bulk edit the records that will be created. This is often very useful when adding many similar records.', + itemId: 'chooseValues' + },{ + html: '
', + style: 'padding-top: 5px;padding-bottom: 5px;' + },{ + xtype: 'form', + itemId: 'theForm', + defaults: { + width: 400, + labelWidth: 140, + border: false + } + },{ + html: '
', + style: 'padding-top: 5px;padding-bottom: 5px;' + },{ + xtype: 'datefield', + itemId: 'StartDate', + fieldLabel: 'Start Date Field' + },{ + xtype: 'datefield', + itemId: 'EndDate', + fieldLabel: 'End Date Field' + },{ + xtype: 'textfield', + itemId: 'waterVolume', + fieldLabel: 'Volume' + },{ + xtype: 'checkcombo', + fieldLabel: 'Frequency' + }], + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + this.getAnimals(); + } + },{ + text: 'Close', + handler: function(btn){ + btn.up('window').hide(); + } + }] + }); + + this.callParent(arguments); + + this.animalHandler(); + }, + + onTypeChange: function(field, val, oldVal){ + if (!val || !val.type) + return; + + var method = val.type + 'Handler'; + LDK.Assert.assertTrue('Unknown handler in AddWaterWindow: ' + method, Ext4.isFunction(this[method])); + + if (Ext4.isFunction(this[method])){ + this[method](); + } + + }, + + animalHandler: function(){ + var form = this.down('#theForm'); + form.removeAll(); + form.add({ + html: 'Either type of cut/paste a list of Animal IDs into the box below. They can be separated by either commas, spaces, or line breaks.', + style: 'padding-bottom: 10px;' + },{ + xtype: 'textarea', + height: 100, + itemId: 'subjArea', + fieldLabel: 'Id(s)' + }); + + form.getAnimals = function(){ + //we clean up, combine subjects + var subjectList = LDK.Utils.splitIds(this.down('#subjArea').getValue(), true); + var startDate = moment(this.down('#StartDate').getValue()); + var endDate = moment(this.down('#EndDate').getValue()); + + + + if(subjectList.length > 0){ + this.addSubjects(subjectList, startDate, endDate) + } + else { + Ext4.Msg.alert('Error', 'Must enter at least 1 animal Id'); + } + } + }, + + addSubjects: function(subjectList, startDate, endDate){ + if (subjectList.length && this.targetStore){ + subjectList = Ext4.Array.unique(subjectList); + if (subjectList.length > this.MAX_ANIMALS){ + Ext4.Msg.alert('Error', 'Too many animals were returned: ' + subjectList.length); + return; + } + + var records = []; + Ext4.Array.forEach(subjectList, function(s){ + var numberOfDays = endDate.diff(startDate, 'days'); + var volume = this.down('#waterVolume').getValue(); + var internalStartDate = moment(startDate); + for (var i =0; i