From 180d542a067473fe5f7bb7e95ec81c26aa260457 Mon Sep 17 00:00:00 2001 From: Binal Date: Tue, 6 Oct 2020 13:39:14 -0700 Subject: [PATCH 01/49] Merge from onprc19.1 r.63271 --- .../resources/schemas/geneticscore.xml | 68 ++ .../GeneticsCore/GeneticsCoreModule.java | 2 +- .../GeneticsCoreNotification.java | 13 + extscheduler/resources/module.xml | 35 + .../resources/schemas/extscheduler.xml | 2 + .../web/extscheduler/App/view/EventForm.js | 71 +- .../web/extscheduler/App/view/Scheduler.js | 1 + .../extscheduler/ExtSchedulerModule.java | 2 +- .../resources/scripts/mergesync/mergesync.js | 4 +- .../queries/onprc_billing/labworkFeeRates.sql | 12 +- .../queries/onprc_billing/leaseFeeRates.sql | 15 +- .../queries/onprc_billing/leaseFees.sql | 127 +- .../queries/onprc_billing/miscCharges.js | 19 +- .../queries/onprc_billing/miscChargesFees.sql | 67 +- .../onprc_billing/miscChargesWithRates.sql | 17 +- .../queries/onprc_billing/perDiemRates.sql | 10 +- .../onprc_billing/procedureFeeRates.sql | 12 +- .../queries/onprc_billing/slaPerDiemRates.sql | 16 +- .../resources/schemas/onprc_billing.xml | 93 +- .../scripts/onprc_billing/billing_triggers.js | 6 +- .../resources/views/invoiceRunDetails.html | 5 +- .../panel/ChargesInstructionPanel.js | 4 +- .../onprc_billing/ONPRC_BillingModule.java | 7 +- .../dataentry/ChargesFormSection.java | 23 + .../dataentry/ChargesFormType.java | 16 + .../notification/FinanceNotification.java | 30 + .../NIHIndustryRates.query.xml | 31 +- .../NIHRateConfig.query.xml | 97 +- .../NIHRateSheet.query.xml | 28 +- .../NIHRateSheet/.qview.xml | 19 +- .../NIHRates_ReducedFA.query.xml | 31 +- .../NIHRates_ReducedFA/.qview.xml | 25 +- onprc_ehr/resources/etls/AvailableBlood.xml | 36 + .../resources/etls/HarvestToPrime_Process.xml | 73 ++ onprc_ehr/resources/etls/TreatmentToDrug.xml | 14 + onprc_ehr/resources/etls/eIACUCToPrimce.xml | 111 ++ .../resources/etls/rateChangeprocess.xml | 27 + .../queries/ehr/SnomedBySetSearch.sql | 75 ++ .../queries/ehr/SnomedBySetSearch/.qview.xml | 14 + .../resources/queries/ehr/project_active.sql | 13 + .../resources/queries/ehr/requests.query.xml | 142 +++ .../resources/queries/ehr/requests/.qview.xml | 28 + .../resources/queries/ehr/snomed_tags.js | 7 + .../queries/onprc_ehr/ChemistryDept.sql | 3 + .../queries/onprc_ehr/NecropsyTask.query.xml | 57 + .../queries/onprc_ehr/NecropsyTask.sql | 22 + .../queries/onprc_ehr/NecropsyTask/.qview.xml | 22 + .../NecropsyTask/ActiveTasks.qview.xml | 23 + .../queries/onprc_ehr/PairingEndType.sql | 7 + .../queries/onprc_ehr/PairingStartType.sql | 5 + .../resources/queries/onprc_ehr/my_tasks.sql | 24 + .../queries/onprc_ehr/my_tasks/.qview.xml | 25 + .../onprc_ehr/my_tasks/Active Tasks.qview.xml | 26 + .../onprc_ehr/my_tasks/Necropsies.qview.xml | 22 + .../my_tasks/Review Required.qview.xml | 26 + .../onprc_ehr/my_tasks/Today.qview.xml | 26 + .../queries/onprc_ehr/userNames.query.xml | 14 + .../resources/queries/onprc_ehr/userNames.sql | 8 + .../queries/study/BCS_Recent_Score.sql | 21 + onprc_ehr/resources/queries/study/Birth.js | 129 ++ .../BirthInitialHousingMismatch.query.xml | 15 + .../study/BirthInitialHousingMismatch.sql | 8 + .../BirthInitialHousingMismatch/.qview.xml | 10 + .../resources/queries/study/BloodCalcBCS.sql | 19 + .../queries/study/CageMateInfant.sql | 25 +- .../study/Clinical Encounters/.qview.xml | 24 + .../queries/study/Clinical Remarks.js | 51 +- .../queries/study/Clinical Remarks.query..xml | 5 +- .../queries/study/Clinical Remarks/.qview.xml | 1 + .../study/Clinical Remarks/CEG_Plan.qview.xml | 21 + .../queries/study/Genetic Ancestry.js | 21 + .../queries/study/Genetic Ancestry.query.xml | 42 + .../queries/study/InfantsBorntoAssigned.sql | 37 + .../study/NecropsyToMiscCharges.query.xml | 57 + .../queries/study/NecropsyToMiscCharges.sql | 32 + .../study/NecropsyToMiscCharges/.qview.xml | 5 + .../queries/study/Pairings.query.xml | 80 +- .../study/ParentageCompleted.query.xml | 52 + .../queries/study/ParentageCompleted.sql | 37 + .../study/ParentageCompleted/.qview.xml | 20 + .../queries/study/SLAOccupiedLocations.sql | 13 + .../study/Weight/Weight Details.qview.xml | 16 + .../resources/queries/study/alopeciaData.sql | 56 +- .../queries/study/alopeciaData/.qview.xml | 13 +- .../queries/study/bloodCalcCriteria.sql | 29 + .../queries/study/bloodCalcFixedRate.sql | 17 + .../queries/study/bloodCalcPastandFuture.sql | 36 + .../study/bloodCalcTotalAllowableBlood.sql | 24 + .../study/bloodCalcTotalAvailableBlood.sql | 22 + .../queries/study/blooddrawDemographics.sql | 35 + .../queries/study/chemPivot.query.xml | 3 +- .../resources/queries/study/chemPivot.sql | 16 +- .../queries/study/chemistryRefRange.sql | 10 +- .../resources/queries/study/clinicalCases.sql | 16 +- .../queries/study/currentBloodAvailable.sql | 15 +- .../queries/study/currentBloodDraws.query.xml | 64 +- .../queries/study/currentBloodDraws.sql | 77 +- .../study/demographicsBloodSummary.query.xml | 75 +- .../study/demographicsBloodSummary.sql | 185 +-- .../study/demographicsBloodSummary/.qview.xml | 22 +- .../demographicsGeneticAncestry.query.xml | 15 + .../study/demographicsGeneticAncestry.sql | 7 + .../study/demographicsMostRecentBCS.sql | 44 +- .../queries/study/demographicsOffspring.sql | 6 +- .../study/demographicsOffspring/.qview.xml | 3 + .../study/demographicsOffspringBSU.query.xml | 59 + .../study/demographicsOffspringBSU.sql | 31 + .../study/demographicsOffspringBSU/.qview.xml | 22 + .../study/demographicsParents.query.xml | 18 + .../queries/study/demographicsParents.sql | 27 +- .../study/demographicsParents/.qview.xml | 2 + .../study/demographicsParentsBSU.query.xml | 59 + .../queries/study/demographicsParentsBSU.sql | 72 ++ .../study/demographicsParentsBSU/.qview.xml | 21 + .../queries/study/geneticAncestry/.qview.xml | 13 + .../geneticAncestry/Active Calls.qview.xml | 8 + .../study/geneticAncestryConflicts.sql | 25 + .../study/geographicOriginConflicts.sql | 8 + .../queries/study/hematologyPivot.query.xml | 3 +- .../queries/study/hematologyPivot.sql | 14 +- .../queries/study/measurementsMisc.sql | 3 +- .../queries/study/measurementsPivotedBody.sql | 5 +- .../study/measurementsPivotedFetal.sql | 5 +- .../study/measurementsPivotedHeart.sql | 5 +- .../study/measurementsPivotedPlacental.sql | 5 +- .../study/measurementsPivotedRawData.sql | 10 +- .../mostRecentObservationsBehavior.query.xml | 11 + .../study/mostRecentObservationsBehavior.sql | 12 + .../mostRecentObservationsBehavior/.qview.xml | 20 + .../Open Behavior Case.qview.xml | 26 + .../queries/study/pairingEvents.query.xml | 39 + .../resources/queries/study/pairingEvents.sql | 39 + .../queries/study/pairingEvents/.qview.xml | 29 + .../queries/study/pairingSummary.query.xml | 55 +- .../queries/study/pairingSummary.sql | 8 +- .../queries/study/pairingSummary/.qview.xml | 15 +- .../study/pairingSummaryComments.query.xml | 39 + .../queries/study/pairingSummaryComments.sql | 24 + .../study/pairingSummaryComments/.qview.xml | 27 + .../queries/study/pairings/.qview.xml | 5 +- .../queries/study/pregnancyGestation.sql | 2 +- .../queries/study/processingSerology.sql | 2 +- .../queries/study/treatmentSchedule.sql | 9 +- .../sqlserver/onprc_ehr-12.395-12.396.sql | 127 ++ .../sqlserver/onprc_ehr-12.397-12.398.sql | 49 + .../sqlserver/onprc_ehr-12.398-12.399.sql | 26 + .../sqlserver/onprc_ehr-12.399-12.400.sql | 32 + .../sqlserver/onprc_ehr-12.400-12.401.sql | 42 + .../sqlserver/onprc_ehr-12.401-12.402.sql | 41 + .../sqlserver/onprc_ehr-12.402-12.403.sql | 28 + .../sqlserver/onprc_ehr-12.403-12.404.sql | 43 + .../sqlserver/onprc_ehr-12.404-12.405.sql | 46 + .../sqlserver/onprc_ehr-12.405-12.406.sql | 126 ++ .../sqlserver/onprc_ehr-12.406-12.407.sql | 126 ++ .../sqlserver/onprc_ehr-12.407-12.408.sql | 54 + .../sqlserver/onprc_ehr-12.408-12.409.sql | 61 + .../sqlserver/onprc_ehr-17.702-17.703.sql | 24 + .../sqlserver/onprc_ehr-17.703-17.704.sql | 16 + .../sqlserver/onprc_ehr-17.704-17.705.sql | 12 + .../scripts/onprc_ehr/onprc_triggers.js | 235 +++- .../views/PE_ExamHistoryReportbyID.html | 63 + .../views/PE_ExamHistoryReportbyID.view.xml | 6 + onprc_ehr/resources/views/animalHistory.html | 19 +- .../resources/views/animalHistory.view.xml | 2 +- onprc_ehr/resources/views/begin.html | 11 +- onprc_ehr/resources/views/datasets.html | 96 ++ onprc_ehr/resources/views/datasets.view.xml | 5 + onprc_ehr/resources/views/enterData.html | 14 + onprc_ehr/resources/views/enterData.view.xml | 9 + onprc_ehr/resources/views/frontPage.html | 28 + onprc_ehr/resources/views/frontPage.view.xml | 5 + .../resources/views/frontPage.webpart.xml | 7 + .../resources/views/groupProcessing.html | 29 +- .../resources/views/printableReports.html | 96 +- .../resources/views/quickSearchonprc.html | 6 +- .../resources/views/serviceRequests.view.xml | 5 +- onprc_ehr/resources/views/vetReview.html | 175 +-- .../web/onprc_ehr/DemographicsRecord.js | 10 +- .../buttons/ClinicalActionsButton.js | 2 +- .../sources/BehaviorExamStoreCollection.js | 138 +++ .../onprc_ehr/data/sources/ONPRCDefaults.js | 167 ++- .../PathologyTissuesStoreCollection.js | 72 ++ .../form/field/AnimalGroupFieldsCombo.js | 34 + .../onprc_ehr/form/field/CEG_PlantextArea.js | 201 +++ .../onprc_ehr/model/sources/ASB_Services.js | 97 +- .../onprc_ehr/model/sources/Biopsy_Staff.js | 65 + .../onprc_ehr/model/sources/ClinicalReport.js | 60 + .../onprc_ehr/model/sources/ClinicalRounds.js | 70 ++ .../onprc_ehr/model/sources/Gross_Finding.css | 4 + .../model/sources/NHPTrainingProperties.js | 29 +- .../model/sources/Pairing_Properties.js | 42 +- .../model/sources/Parentage_Properties.js | 26 + .../model/sources/PathologyTissues.js | 40 + .../model/sources/Pathology_Notes.js | 51 + .../model/sources/ProjectAnimalConditions.js | 16 +- .../model/sources/ResearchProcedures.js | 92 ++ .../onprc_ehr/model/sources/SurgeryBlood.js | 25 + .../onprc_ehr/model/sources/Surgery_Staff.js | 64 + .../resources/web/onprc_ehr/onprcOverrides.js | 23 + .../resources/web/onprc_ehr/onprcReports.js | 134 +- .../panel/AddScheduledTreatmentPanel.js | 1 + .../onprc_ehr/panel/AnimalDetailsCasePanel.js | 2 +- .../web/onprc_ehr/panel/BloodSummaryPanel.js | 98 +- .../web/onprc_ehr/panel/EnterDataPanel.js | 519 ++++++++ .../web/onprc_ehr/panel/LockAnimalsPanel.js | 3 + .../web/onprc_ehr/panel/ManageCasesPanel.js | 1074 +++++++++++++++++ .../onprc_ehr/panel/ManageTreatmentsPanel.js | 8 +- .../onprc_ehr/panel/MultiAnimalFilterType.js | 321 +++++ .../web/onprc_ehr/panel/RoomLayoutPanel.js | 2 +- .../onprc_ehr/panel/ServiceRequestsPanel.js | 179 +++ .../web/onprc_ehr/panel/SnapshotPanel.js | 142 ++- .../web/onprc_ehr/window/AddAnimalsWindow.js | 394 ++++++ .../window/AddClinicalCasesWindow.js | 564 +++++++++ .../onprc_ehr/window/BulkChangeCasesWindow.js | 3 +- .../window/BulkStrokeRoundsWindow.js | 8 +- .../web/onprc_ehr/window/CopyTaskWindow.js | 317 +++++ .../web/onprc_ehr/window/ManageCasesWindow.js | 51 + .../onprc_ehr/window/ManageRecordWindow.js | 207 ++++ .../window/MarkAssignmentCompletedWindow.js | 5 +- .../ONPRC_AddScheduledTreatmentWindow.js | 41 +- .../window/SurgeryPostOpMedsWindow.js | 483 ++++++++ .../labkey/onprc_ehr/ONPRC_EHRManager.java | 2 + .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 112 +- .../dataentry/ASBRequestFormType.java | 15 +- .../dataentry/AuxProcedureFormType.java | 3 +- .../dataentry/BehaviorExamFormType.java | 12 + .../onprc_ehr/dataentry/BiopsyFormType.java | 1 + .../CagemateClinicalReportFormType.java | 81 ++ .../dataentry/ClinicalReportFormType.java | 15 +- .../dataentry/ClinicalRoundsFormType.java | 4 +- .../EncounterProcedureFormSection.java | 40 + .../dataentry/GeneticAncestryFormType.java | 45 + .../GrossFindingsFormPanelSection.java | 3 + .../dataentry/NHPRProcessingFormType.java | 59 + .../dataentry/ParentageFormType.java | 12 + .../PathologyDiagnosesFormSection.java | 11 + .../dataentry/PathologyTissuesFormType.java | 12 +- .../ProcedureRequestBulkEditFormType.java | 27 + .../dataentry/SingleSurgeryFormType.java | 6 + .../onprc_ehr/dataentry/SurgeryFormType.java | 6 + .../dataentry/SurgicalRoundsFormType.java | 17 + .../dataentry/TissueDistFormSection.java | 10 + .../TissueMeasurementsFormSection.java | 45 + .../dataentry/TissueWeightsFormSection.java | 46 + .../onprc_ehr/dataentry/WeightFormType.java | 17 + ...ActiveTreatmentsXDemographicsProvider.java | 94 ++ .../AssignedVetDemographicsProvider.java | 4 +- .../FosterChildDemographicsProvider.java | 13 +- .../GeneticAncestryDemographicsProvider.java | 41 + .../ONPRCClinicalRemarksDataSource.java | 118 ++ .../history/ONPRCiStatLabworkType.java | 40 + .../notification/BSUNotesNotification.java | 59 + .../notification/BehaviorNotification.java | 6 +- .../BirthHousingMismatchNotification.java | 60 + .../ColonyAlertsNotification.java | 101 +- .../notification/DCMNotesNotification.java | 58 + .../InfantsBornAssignedNotification.java | 172 +++ .../PregnantNHPsGestationAlert.java | 62 + .../RoutineClinicalTestsNotification.java | 6 +- .../TreatmentAlertsPostOpsNotification.java | 6 +- .../UnoccupiedRoomsNotification.java | 85 +- .../query/ONPRC_EHRTriggerHelper.java | 381 ++++-- .../onprc_ehr/table/ONPRC_EHRCustomizer.java | 47 + .../study/processingBloodDraws.query.xml | 3 + .../queries/study/processingBloodDraws.sql | 9 +- .../study/processingBloodDraws/.qview.xml | 27 +- .../study/processingGeneticsBloodDraws.sql | 20 +- .../resources/queries/study/samples.sql | 3 +- .../resources/queries/onprc_ssu/schedule.js | 2 - .../queries/sla/ProtocolProjectsUsage.sql | 23 +- sla/resources/queries/sla/SLACageSize.sql | 9 +- sla/resources/queries/sla/SLACageType.sql | 9 +- .../sla_public/PurchaseOrderDetailsAdmin.sql | 4 +- sla/resources/schemas/sla.xml | 4 +- .../web/sla/form/CreatePurchaseOrder.js | 247 +++- sla/resources/web/sla/form/PurchaseOrder.css | 5 + .../web/sla/form/PurchaseOrderDashboard.js | 2 +- .../web/sla/form/PurchaseOrderDetails.js | 3 +- .../web/sla/form/PurchaseSpeciesGrid.js | 2 +- .../queries/study/treatmentScheduleUpdate.sql | 5 +- 280 files changed, 12735 insertions(+), 1210 deletions(-) create mode 100644 onprc_ehr/resources/etls/AvailableBlood.xml create mode 100644 onprc_ehr/resources/etls/HarvestToPrime_Process.xml create mode 100644 onprc_ehr/resources/etls/TreatmentToDrug.xml create mode 100644 onprc_ehr/resources/etls/eIACUCToPrimce.xml create mode 100644 onprc_ehr/resources/etls/rateChangeprocess.xml create mode 100644 onprc_ehr/resources/queries/ehr/SnomedBySetSearch.sql create mode 100644 onprc_ehr/resources/queries/ehr/SnomedBySetSearch/.qview.xml create mode 100644 onprc_ehr/resources/queries/ehr/project_active.sql create mode 100644 onprc_ehr/resources/queries/ehr/requests.query.xml create mode 100644 onprc_ehr/resources/queries/ehr/requests/.qview.xml create mode 100644 onprc_ehr/resources/queries/ehr/snomed_tags.js create mode 100644 onprc_ehr/resources/queries/onprc_ehr/ChemistryDept.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.query.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/ActiveTasks.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/PairingEndType.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/PairingStartType.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/my_tasks.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/my_tasks/.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/my_tasks/Active Tasks.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/my_tasks/Necropsies.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/my_tasks/Review Required.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/my_tasks/Today.qview.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/userNames.query.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/userNames.sql create mode 100644 onprc_ehr/resources/queries/study/BCS_Recent_Score.sql create mode 100644 onprc_ehr/resources/queries/study/Birth.js create mode 100644 onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.query.xml create mode 100644 onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.sql create mode 100644 onprc_ehr/resources/queries/study/BirthInitialHousingMismatch/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/BloodCalcBCS.sql create mode 100644 onprc_ehr/resources/queries/study/Clinical Encounters/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/Clinical Remarks/CEG_Plan.qview.xml create mode 100644 onprc_ehr/resources/queries/study/Genetic Ancestry.js create mode 100644 onprc_ehr/resources/queries/study/Genetic Ancestry.query.xml create mode 100644 onprc_ehr/resources/queries/study/InfantsBorntoAssigned.sql create mode 100644 onprc_ehr/resources/queries/study/NecropsyToMiscCharges.query.xml create mode 100644 onprc_ehr/resources/queries/study/NecropsyToMiscCharges.sql create mode 100644 onprc_ehr/resources/queries/study/NecropsyToMiscCharges/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/ParentageCompleted.query.xml create mode 100644 onprc_ehr/resources/queries/study/ParentageCompleted.sql create mode 100644 onprc_ehr/resources/queries/study/ParentageCompleted/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/SLAOccupiedLocations.sql create mode 100644 onprc_ehr/resources/queries/study/Weight/Weight Details.qview.xml create mode 100644 onprc_ehr/resources/queries/study/bloodCalcCriteria.sql create mode 100644 onprc_ehr/resources/queries/study/bloodCalcFixedRate.sql create mode 100644 onprc_ehr/resources/queries/study/bloodCalcPastandFuture.sql create mode 100644 onprc_ehr/resources/queries/study/bloodCalcTotalAllowableBlood.sql create mode 100644 onprc_ehr/resources/queries/study/bloodCalcTotalAvailableBlood.sql create mode 100644 onprc_ehr/resources/queries/study/blooddrawDemographics.sql create mode 100644 onprc_ehr/resources/queries/study/demographicsGeneticAncestry.query.xml create mode 100644 onprc_ehr/resources/queries/study/demographicsGeneticAncestry.sql create mode 100644 onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml create mode 100644 onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql create mode 100644 onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml create mode 100644 onprc_ehr/resources/queries/study/demographicsParentsBSU.sql create mode 100644 onprc_ehr/resources/queries/study/demographicsParentsBSU/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/geneticAncestry/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/geneticAncestry/Active Calls.qview.xml create mode 100644 onprc_ehr/resources/queries/study/geneticAncestryConflicts.sql create mode 100644 onprc_ehr/resources/queries/study/geographicOriginConflicts.sql create mode 100644 onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.query.xml create mode 100644 onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql create mode 100644 onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml create mode 100644 onprc_ehr/resources/queries/study/pairingEvents.query.xml create mode 100644 onprc_ehr/resources/queries/study/pairingEvents.sql create mode 100644 onprc_ehr/resources/queries/study/pairingEvents/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml create mode 100644 onprc_ehr/resources/queries/study/pairingSummaryComments.sql create mode 100644 onprc_ehr/resources/queries/study/pairingSummaryComments/.qview.xml create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.397-12.398.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.398-12.399.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.399-12.400.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.400-12.401.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.401-12.402.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.402-12.403.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.403-12.404.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.404-12.405.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.702-17.703.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.703-17.704.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.704-17.705.sql create mode 100644 onprc_ehr/resources/views/PE_ExamHistoryReportbyID.html create mode 100644 onprc_ehr/resources/views/PE_ExamHistoryReportbyID.view.xml create mode 100644 onprc_ehr/resources/views/datasets.html create mode 100644 onprc_ehr/resources/views/datasets.view.xml create mode 100644 onprc_ehr/resources/views/enterData.html create mode 100644 onprc_ehr/resources/views/enterData.view.xml create mode 100644 onprc_ehr/resources/views/frontPage.html create mode 100644 onprc_ehr/resources/views/frontPage.view.xml create mode 100644 onprc_ehr/resources/views/frontPage.webpart.xml create mode 100644 onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/data/sources/PathologyTissuesStoreCollection.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/form/field/AnimalGroupFieldsCombo.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/form/field/CEG_PlantextArea.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/Biopsy_Staff.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalReport.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalRounds.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/Parentage_Properties.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/PathologyTissues.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/Surgery_Staff.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/onprcOverrides.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/panel/ManageCasesPanel.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/panel/MultiAnimalFilterType.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/panel/ServiceRequestsPanel.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/AddAnimalsWindow.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/AddClinicalCasesWindow.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/CopyTaskWindow.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/ManageCasesWindow.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/ManageRecordWindow.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/SurgeryPostOpMedsWindow.js create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GeneticAncestryFormType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ProcedureRequestBulkEditFormType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveTreatmentsXDemographicsProvider.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/demographics/GeneticAncestryDemographicsProvider.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCClinicalRemarksDataSource.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCiStatLabworkType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/BSUNotesNotification.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/BirthHousingMismatchNotification.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/DCMNotesNotification.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/PregnantNHPsGestationAlert.java diff --git a/GeneticsCore/resources/schemas/geneticscore.xml b/GeneticsCore/resources/schemas/geneticscore.xml index a5a4c1309..1de9bde1c 100644 --- a/GeneticsCore/resources/schemas/geneticscore.xml +++ b/GeneticsCore/resources/schemas/geneticscore.xml @@ -58,6 +58,74 @@ + + + + + org.labkey.ldk.query.DefaultTableCustomizer + Taqman Probes + rowId + + + Row Id + + + + + + + + + Folder + + + + + + + + + + + + + + + + + org.labkey.ldk.query.DefaultTableCustomizer + Genetic Test Significance + rowId + + + Row Id + + + + + + + + + + + + + + + Folder + + + + + + + + + + + + diff --git a/GeneticsCore/src/org/labkey/GeneticsCore/GeneticsCoreModule.java b/GeneticsCore/src/org/labkey/GeneticsCore/GeneticsCoreModule.java index e108e5ba4..ad2afdfca 100644 --- a/GeneticsCore/src/org/labkey/GeneticsCore/GeneticsCoreModule.java +++ b/GeneticsCore/src/org/labkey/GeneticsCore/GeneticsCoreModule.java @@ -39,7 +39,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 17.10; + return 17.11; } @Override diff --git a/GeneticsCore/src/org/labkey/GeneticsCore/notification/GeneticsCoreNotification.java b/GeneticsCore/src/org/labkey/GeneticsCore/notification/GeneticsCoreNotification.java index 93663dff3..9639c1db1 100644 --- a/GeneticsCore/src/org/labkey/GeneticsCore/notification/GeneticsCoreNotification.java +++ b/GeneticsCore/src/org/labkey/GeneticsCore/notification/GeneticsCoreNotification.java @@ -106,6 +106,7 @@ public String getMessageBodyHTML(Container c, User u) getParentageFreezerSamplesNotFlagged(c, u, msg); getParentageConflicts(c, u, msg); + getAncestryConflicts(c, u, msg); return msg.toString(); } @@ -157,6 +158,18 @@ public void getParentageConflicts(Container c, User u, StringBuilder msg) } } + public void getAncestryConflicts(Container c, User u, StringBuilder msg) + { + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("geneticAncestryConflicts"); + TableSelector ts = new TableSelector(ti, PageFlowUtil.set("Id")); + long count = ts.getRowCount(); + if (count > 0) + { + ActionURL url = QueryService.get().urlFor(u, c, QueryAction.executeQuery, "study", "geneticAncestryConflicts"); + msg.append("WARNING: There are " + count + " animals with duplicate or conflicting genetic ancestry calls.

Click here to view these animals


"); + } + } + public void getActiveExclusions(Container c, User u, StringBuilder msg, String flag, int interval) { SimpleFilter filter = new SimpleFilter(); diff --git a/extscheduler/resources/module.xml b/extscheduler/resources/module.xml index 6f39e879a..c67e137ca 100644 --- a/extscheduler/resources/module.xml +++ b/extscheduler/resources/module.xml @@ -2,10 +2,45 @@ The group name to be used for the set of users to display in the Scheduler app UserId combobox for creating new events. + true true ADMIN + + + Length in minutes for event period when creating a new event. + true + true + 30 + + ADMIN + + + + + A comma separated list of column names to display for the EventForm.js file. Column Names(Name,ResourceId,UserId,Alias,Quantity,Comments,StartDate,EndDate) + true + true + Name,ResourceId,UserId,Alias,Quantity,Comments,StartDate,EndDate + + ADMIN + + + + + Set as true to allow for calendar events to overlap for a given resource. Defaults to false when blank. + true + select + + + true + false + + ADMIN + + diff --git a/extscheduler/resources/schemas/extscheduler.xml b/extscheduler/resources/schemas/extscheduler.xml index 6db905b6e..48ee9f647 100644 --- a/extscheduler/resources/schemas/extscheduler.xml +++ b/extscheduler/resources/schemas/extscheduler.xml @@ -52,6 +52,8 @@ + + User diff --git a/extscheduler/resources/web/extscheduler/App/view/EventForm.js b/extscheduler/resources/web/extscheduler/App/view/EventForm.js index 23e33cb32..352f503d6 100644 --- a/extscheduler/resources/web/extscheduler/App/view/EventForm.js +++ b/extscheduler/resources/web/extscheduler/App/view/EventForm.js @@ -13,8 +13,14 @@ Ext.define('App.view.EventForm', { editable : false, scheduler : null, + eventPeriodLength: 30, + initComponent: function() { + var context = LABKEY.getModuleContext('extscheduler'); + this.eventPeriodLength = parseInt(context['ExtSchedulerEventPeriodLength']); + this.eventFormColumns = context['ExtSchedulerEventFormColumns'].split(','); + this.items = [ //{ // xtype : 'textfield', @@ -22,6 +28,7 @@ Ext.define('App.view.EventForm', { // name : 'Name', // reference : 'eventNameField', // allowBlank : !this.editable, + // hidden : this.eventFormColumns.indexOf('Name') === -1, // bind : { // value : '{eventRecord.Name}', // readOnly : !this.editable @@ -33,9 +40,11 @@ Ext.define('App.view.EventForm', { name : 'ResourceId', reference : 'eventResourceField', allowBlank : !this.editable, + hidden : this.eventFormColumns.indexOf('ResourceId') === -1, bind : { value : '{eventRecord.ResourceId}', readOnly : !this.editable + } }, { @@ -49,25 +58,56 @@ Ext.define('App.view.EventForm', { editable : false, typeAhead : true, allowBlank : !this.editable, + hidden : this.eventFormColumns.indexOf('UserId') === -1, bind : { value : '{eventRecord.UserId}', readOnly : !this.editable } }, - // { - // xtype : 'textfield', - // fieldLabel : 'Alias', - // name : 'Alias', - // reference : 'eventAliasField', - // allowBlank : !this.editable, - // bind : { - // value : '{eventRecord.Alias}', - // readOnly : !this.editable - // } - // }, + { + xtype : 'textfield', + fieldLabel : 'Alias', + name : 'Alias', + reference : 'eventAliasField', + //allowBlank : !this.editable, + allowBlank: true, + hidden : this.eventFormColumns.indexOf('Alias') === -1, + bind : { + value : '{eventRecord.Alias}', + readOnly : !this.editable + } + }, + { + xtype : 'numberfield', + fieldLabel : 'Quantity', + name : 'Quantity', + value : 1, + minValue: 1, + allowDecimals : false, + reference : 'eventQuantityField', + allowBlank : !this.editable, + hidden : this.eventFormColumns.indexOf('Quantity') === -1, + bind : { + value : '{eventRecord.Quantity}', + readOnly : !this.editable + } + }, + { + xtype : 'textfield', + fieldLabel : 'Comments', + name : 'Comments', + reference : 'eventCommentsField', + allowBlank : true, + hidden : this.eventFormColumns.indexOf('Comments') === -1, + bind : { + value : '{eventRecord.Comments}', + readOnly : !this.editable + } + }, { xtype : 'fieldcontainer', layout : 'hbox', + hidden : this.eventFormColumns.indexOf('StartDate') === -1, items : [ this.getStartDateField(), this.getStartTimeField() @@ -76,6 +116,7 @@ Ext.define('App.view.EventForm', { { xtype : 'fieldcontainer', layout : 'hbox', + hidden : this.eventFormColumns.indexOf('EndDate') === -1, items : [ this.getEndDateField(), this.getEndTimeField() @@ -187,7 +228,7 @@ Ext.define('App.view.EventForm', { width : 90, name : 'StartTime', format : 'H:i', - increment : 30, + increment : this.eventPeriodLength, allowBlank : !this.editable, bind : { minValue : '{defaultMinTime}', @@ -200,7 +241,7 @@ Ext.define('App.view.EventForm', { this.startTimeField.on('change', function(timefield, newValue){ if (this.getEndTimeField().getValue() == null) - this.getEndTimeField().setValue(new Date(newValue.getTime() + (30*60*1000))); + this.getEndTimeField().setValue(new Date(newValue.getTime() + (this.eventPeriodLength*60*1000))); this.ensureEndTimeAfterStart(); }, this); @@ -245,7 +286,7 @@ Ext.define('App.view.EventForm', { name : 'EndTime', width : 90, format : 'H:i', - increment : 30, + increment : this.eventPeriodLength, allowBlank : !this.editable, bind : { minValue : '{minEndTime}', @@ -274,7 +315,7 @@ Ext.define('App.view.EventForm', { if (allNonNull && startDate.getTime() == endDate.getTime()) { - var d = new Date(startTime.getTime() + (30*60*1000)); + var d = new Date(startTime.getTime() + (this.eventPeriodLength*60*1000)); this.getEndTimeField().setMinValue(d); if (startTime.getTime() >= endTime.getTime()) diff --git a/extscheduler/resources/web/extscheduler/App/view/Scheduler.js b/extscheduler/resources/web/extscheduler/App/view/Scheduler.js index d06ceb5fb..3cf7c3587 100644 --- a/extscheduler/resources/web/extscheduler/App/view/Scheduler.js +++ b/extscheduler/resources/web/extscheduler/App/view/Scheduler.js @@ -17,6 +17,7 @@ Ext.define('App.view.Scheduler', { eventResizeHandles : 'none', eventBodyTemplate :'{Name:htmlEncode}
{ResourceName:htmlEncode}
{UserDisplayName:htmlEncode}', snapToIncrement : true, + allowOverlap : true, highlightCurrentTime : true, calendarTimeAxisCfg : { height : 30 diff --git a/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java b/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java index 2762d398d..3ff8a1b7e 100644 --- a/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java +++ b/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java @@ -26,7 +26,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 15.28; + return 15.31; } @Override diff --git a/mergesync/resources/scripts/mergesync/mergesync.js b/mergesync/resources/scripts/mergesync/mergesync.js index ff7feec7e..1b7fe4d1a 100644 --- a/mergesync/resources/scripts/mergesync/mergesync.js +++ b/mergesync/resources/scripts/mergesync/mergesync.js @@ -7,7 +7,7 @@ var console = require("console"); var LABKEY = require("labkey"); exports.init = function(EHR){ - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.COMPLETE, 'study', 'Clinpath Runs', function(event, errors, helper){ + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.COMPLETE, 'study', 'clinpathruns', function(event, errors, helper){ var rows = helper.getRows(); if (helper.getEvent() == 'insert' && rows.length && !helper.isValidateOnly()){ var toSync = []; @@ -37,7 +37,7 @@ exports.init = function(EHR){ } }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_DELETE, 'study', 'Clinpath Runs', function(helper, errors, row) { + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_DELETE, 'study', 'clinpathruns', function(helper, errors, row) { if (row.objectid){ var mergeHelper = new org.labkey.mergesync.RequestSyncHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); mergeHelper.deleteSyncRecords(row.objectid); diff --git a/onprc_billing/resources/queries/onprc_billing/labworkFeeRates.sql b/onprc_billing/resources/queries/onprc_billing/labworkFeeRates.sql index 29f8d8f5c..ff4298464 100644 --- a/onprc_billing/resources/queries/onprc_billing/labworkFeeRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/labworkFeeRates.sql @@ -38,15 +38,23 @@ SELECT WHEN (alias.category IS NOT NULL AND alias.category != 'OGA') THEN cr.unitCost --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null + --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + --WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN + ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) + --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) + --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + --WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) + --the NIH rate ELSE cr.unitCost END AS DOUBLE), 2) as unitCost, + cr.unitCost as nihRate, 1 as quantity, COALESCE(cu.account, cast(ce.account as varchar(100))) as creditAccount, diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates.sql b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates.sql index 85a2d9540..ffabcf77b 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates.sql @@ -1,3 +1,4 @@ + /* * Copyright (c) 2013 LabKey Corporation * @@ -114,11 +115,11 @@ SELECT --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) - --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + --raise F&A on ly + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) --the NIH rate ELSE cr.unitCost END AS DOUBLE) as unitCost1, @@ -138,11 +139,11 @@ SELECT --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr2.unitCost / (1 - COALESCE(cr2.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr2.unitCost / (1 - COALESCE(cr2.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate))) ELSE 1 END)) --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr2.unitCost / (1 - COALESCE(cr2.subsidy, 0))) --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr2.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr2.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate))) ELSE 1 END)) --the NIH rate ELSE cr2.unitCost END AS DOUBLE) as unitCost2, @@ -162,11 +163,11 @@ SELECT --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr3.unitCost / (1 - COALESCE(cr3.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr3.unitCost / (1 - COALESCE(cr3.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / ( 1 + alias.faRate))) ELSE 1 END)) --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr3.unitCost / (1 - COALESCE(cr3.subsidy, 0))) --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr3.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr3.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate))) ELSE 1 END)) --the NIH rate ELSE cr3.unitCost END AS DOUBLE) as unitCost3, diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFees.sql b/onprc_billing/resources/queries/onprc_billing/leaseFees.sql index 60486916f..556e4d410 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFees.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFees.sql @@ -2,7 +2,9 @@ PARAMETERS(StartDate TIMESTAMP, EndDate TIMESTAMP) SELECT a.id, +--This shoould compare finalized to assignent date which is date a.date, + a.project, a.date as assignmentStart, a.enddate, @@ -10,19 +12,74 @@ a.projectedReleaseCondition, a.releaseCondition, a.assignCondition, a.releaseType, +a5.id as ESPFAnimal, a.ageAtTime.AgeAtTimeYearsRounded as ageAtTime, 'Lease Fees' as category, + +--determine if the animal is assigned to U42 ESPF + + CASE +-- Determine if the animal is currently a n Obese Animal +-- Deermines if the animal is part of 0833 +-- TODO Need to change the Day lease to release date instead of projected release date +When a5.id is not Null + then '5348' + -- then (Select c.rowid from chargeableItems c where c.itemCode = '1077') +-- remove setup fee from Day Leases + When (a3.id IS NOT NULL + and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)<= 14 AND a.enddate IS NULL)) + AND a.assignCondition = a.projectedreleasecondition + then (Select c.rowid from chargeableItems c where c.itemCode = 'ONR01') + --short term obese lease + When (a3.id is Not Null + and ((TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease) > 14) + and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)< 90)) + AND a.assignCondition = a.projectedreleasecondition + AND a.enddate IS NULL) + then (Select c.rowid from "/ONPRC/Admin/Finance".onprc_billing.chargeableItems c where c.itemCode = 'ONR24') + --obese long term terminal assignment + When (a3.Id is not Null AND ((TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) > 90 ) AND a.enddate is NULL and a.projectedReleaseCondition = 206) + then (Select c.rowid from "/ONPRC/Admin/Finance".onprc_billing.chargeableItems c where c.itemCode = 'ONR45') + --obese long term + When (a3.id Is Not NUll + and ((TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)> 90 ) AND a.enddate IS NULL)) + then (Select c.rowid from "/ONPRC/Admin/Finance".onprc_billing.chargeableItems c where c.itemCode = 'ONR25') + +--Infant/Dam Day Lease + + When (a4.id is not null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) <=14 and a.endDate is null and a.ageAtTime.AgeAtTimeYearsRounded < 1 + and a.remark like '%Diet%') + then (Select c.rowid from "/ONPRC/Admin/Finance".onprc_billing.chargeableItems c where c.itemCode = 'ONR40') + When (a4.id is not null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) <=14 and a.endDate is null and a.ageAtTime.AgeAtTimeYearsRounded < 1 + and a.remark like 'Control%') + then (Select c.rowid from "/ONPRC/Admin/Finance".onprc_billing.chargeableItems c where c.itemCode = 'ONR41') + When (a4.id is not null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) <=14 and a.endDate is null and a.ageAtTime.AgeAtTimeYearsRounded < 1) + then (Select c.rowid from "/ONPRC/Admin/Finance".onprc_billing.chargeableItems c where c.itemCode = 'ONR44') + WHEN (a.duration <= CAST(javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.DAY_LEASE_MAX_DURATION') as INTEGER) AND a.enddate IS NOT NULL AND a.assignCondition = a.releaseCondition) THEN (SELECT rowid FROM onprc_billing_public.chargeableItems ci WHERE ci.active = true AND ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.DAY_LEASE_NAME')) WHEN (a.duration <= CAST(javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.DAY_LEASE_MAX_DURATION') as INTEGER) AND a.enddate IS NOT NULL AND a.assignCondition = a.releaseCondition) THEN (SELECT rowid FROM onprc_billing_public.chargeableItems ci WHERE ci.active = true AND ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.DAY_LEASE_NAME')) WHEN a2.id IS NOT NULL THEN (SELECT rowid FROM onprc_billing_public.chargeableItems ci WHERE (ci.startDate <= a.date and ci.endDate >= a.date) AND ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.TMB_LEASE_NAME')) ELSE lf.chargeId END as chargeId, --special case one-day lease rates. note: if enddate is null, these cannot be a one-day lease CASE - WHEN (Select Count(*) from study.birth b - left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a1 on b.id = a.id and a.date = b.dateOnly and a.project.use_category in ('Center Resource','U42','U24') - left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 on b.dam = a2.id and a2.project.use_category in ('Center Resource','U42','U24') and (a2.date <= b.dateOnly and a2.endDate >=b.dateOnly or a2.enddate is Null) + WHen a3.id is not Null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) >14 Then 1 + WHen a4.id is not Null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) >14 Then 1 + WHen a3.id is not Null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) <=14 Then (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) + WHen a4.id is not Null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) <=14 Then (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) + WHen a4.id is not Null and (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) >14 Then (TIMESTAMPDIFF('SQL_TSI_Day',a.date,a.projectedRelease)) +--this looks for TMB INfant and sets count to 0. Based on Mom being TMB + + WHEN (Select Count(*) from study.birth b + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a1 on b.id = a.id and a.date = b.dateOnly + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 on b.dam = a2.id and a2.project = 559 and (a2.date <= b.dateOnly and a2.endDate >=b.dateOnly or a2.enddate is Null) + where b.id = a.id and a1.project.protocol != a2.project.protocol) > 0 THEN 0 +--infdants born to resource dams + WHEN (Select Count(*) from study.birth b + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a1 on b.id = a.id and a.date = b.dateOnly and a.project.use_category in ('Center Resource','U42','U24') + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 on b.dam = a2.id and a2.project.use_category in ('Center Resource','U42','U24') and (a2.date <= b.dateOnly and a2.endDate >=b.dateOnly or a2.enddate is Null) where b.id = a.id and a1.project.protocol = a2.project.protocol) > 0 THEN 0 + WHEN (a.duration = 0 AND a.enddate IS NOT NULL AND a.assignCondition = a.releaseCondition) THEN 1 WHEN (fl.id Is Not Null) THEN 0 --This will check for infants born to resource moms and will not charge @@ -37,7 +94,6 @@ null as chargeCategory, null as isAdjustment, a.datefinalized, a.enddatefinalized - FROM study.assignment a --find overlapping TMB at date of assignment @@ -48,19 +104,50 @@ LEFT JOIN study.assignment a2 ON ( AND a2.project.name = javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.TMB_PROJECT') ) + +--Obese 0833 animals id 1609 +LEFt join onprc_billing.assignment_ObseseResource a3 on + ( a.id = a3.id and a.project !=a3.project + and a3.project = 1609 + and a3.dateonly <=a.dateOnly + AND a3.endDateCoalesced >= a.dateOnly) + +--Obese 0622-01 animals id 1082 +LEFt join onprc_billing.assignment_ObseseResource a4 on + ( a.id = a4.id and a.project !=a4.project + and a4.project = 1082 + and a4.dateonly <=a.dateOnly + AND a4.endDateCoalesced >= a.dateOnly) + + + + + +--espf animals being dual assigned +LEFt join assignment_U42ESPF a5 on + ( a.id = a5.id and a.project !=a5.project + and a5.project = 1107 + and a5.dateonly <=a.dateOnly + AND a5.endDateCoalesced >= a.dateOnly) + LEFT JOIN onprc_billing.leaseFeeDefinition lf ON ( - lf.assignCondition = a.assignCondition - AND lf.releaseCondition = a.projectedReleaseCondition - AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf.minAge OR lf.minAge IS NULL) - AND (a.ageAtTime.AgeAtTimeYearsRounded < lf.maxAge OR lf.maxAge IS NULL) - AND lf.active = true + a3.Id is null and a4.id is Null and a5.id is Null And + lf.assignCondition = a.assignCondition + AND lf.releaseCondition = a.projectedReleaseCondition + AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf.minAge OR lf.minAge IS NULL) + AND (a.ageAtTime.AgeAtTimeYearsRounded < lf.maxAge OR lf.maxAge IS NULL) + AND lf.active = true ) + + + --adds the reasearch owned animal exemption Left JOIN study.flags fl on (a.id = fl.id and fl.flag.code = 4034 and (a.date >= fl.date and a.date <=COALESCE(fl.enddate,Now()) )) + WHERE CAST(a.datefinalized AS DATE) >= CAST(STARTDATE as DATE) AND CAST(a.datefinalized AS DATE) <= CAST(ENDDATE as DATE) AND a.qcstate.publicdata = true --and a.participantID.demographics.species.common not in ('Rabbit','Guinea Pigs') @@ -78,6 +165,7 @@ SELECT a.assignCondition, a.releaseType, a.ageAtTime.AgeAtTimeYearsRounded as ageAtTime, + ' ' as ESPFAnimal, 'Lease Setup Fees' as category, (SELECT rowid FROM onprc_billing_public.chargeableItems ci WHERE ci.active = true AND ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.LEASE_SETUP_FEES')) as chargeId, 1 as quantity, @@ -94,7 +182,7 @@ FROM study.assignment a WHERE CAST(a.datefinalized AS DATE) >= CAST(STARTDATE as DATE) AND CAST(a.datefinalized AS DATE) <= CAST(ENDDATE as DATE) AND a.qcstate.publicdata = true --only charge setup fee for leases >24H. note: duration assumes today as end, so exclude null enddates -AND (a.duration > CAST(javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.DAY_LEASE_MAX_DURATION') as INTEGER) OR a.assignCondition != a.releaseCondition OR a.enddate IS NULL) +AND ((a.duration > CAST(javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.DAY_LEASE_MAX_DURATION') as INTEGER)) OR ( a.assignCondition != a.releaseCondition AND a.enddate IS NULL)) and a.id.demographics.species Not IN ('Rabbit','Guinea Pigs') --add released animals that need adjustments @@ -102,7 +190,11 @@ UNION ALL SELECT a.id, -a.enddate as date, --use enddate as the transaction date for this charge +case + When a.enddate < a.dateFinalized then a.dateFinalized + Else a.enddate + End as date, +--a.date, a.project, a.date as assignmentStart, a.enddate, @@ -111,7 +203,9 @@ a.releaseCondition, a.assignCondition, a.releaseType, a.ageAtTime.AgeAtTimeYearsRounded as ageAtTime, +a5.id as ESPFAnimal, 'Lease Fees' as category, +--////This selectes the charge ID to be used (SELECT max(rowid) as rowid FROM onprc_billing_public.chargeableItems ci WHERE ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.LEASE_FEE_ADJUSTMENT') and ci.active = true) as chargeId, CASE when (fl.id Is Not Null) then 0 @@ -147,9 +241,13 @@ LEFT JOIN onprc_billing.leaseFeeDefinition lf2 AND a2.dateOnly <= a.dateOnly AND a2.endDateCoalesced >= a.dateOnly AND a2.project.name = javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.TMB_PROJECT') - - ) +LEFt join assignment_U42ESPF a5 on + ( a.id = a5.id and a.project !=a5.project + and a5.project = 1107 + and a5.dateonly <=a.dateOnly + AND a5.endDateCoalesced >= a.dateOnly) + --adds the reasearch owned animal exemption Left JOIN study.flags fl on (a.id = fl.id @@ -157,6 +255,7 @@ Left JOIN study.flags fl on and (a.date >= fl.date and a.date <=COALESCE(fl.enddate,Now()) )) WHERE a.releaseCondition != a.projectedReleaseCondition +and (A.id != A5.id or A5.id is Null) AND a.enddatefinalized is not null AND CAST(a.enddatefinalized AS DATE) >= CAST(STARTDATE AS DATE) AND CAST(a.enddatefinalized AS DATE) <= CAST(EndDate as DATE) AND a.qcstate.publicdata = true AND lf.active = true -AND a2.id IS NULL and a.participantID not like '[a-z]%' \ No newline at end of file +AND a2.id IS NULL and a.participantID not like '[a-z]%' diff --git a/onprc_billing/resources/queries/onprc_billing/miscCharges.js b/onprc_billing/resources/queries/onprc_billing/miscCharges.js index 167f8f3d0..9835b5071 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscCharges.js +++ b/onprc_billing/resources/queries/onprc_billing/miscCharges.js @@ -32,20 +32,19 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even } if (row.debitedaccount){ - row.debitedaccount = row.debitedaccount.replace(/^\s+|\s+$/g, '') + row.debitedaccount = row.debitedaccount.replace(/^\s+|\s+$/g, ''); } - if (row.creditedaccount){ - row.creditedaccount = row.creditedaccount.replace(/^\s+|\s+$/g, '') + if (row.creditedaccount) { + row.creditedaccount = row.creditedaccount.replace(/^\s+|\s+$/g, ''); } - if (row.chargeId){ - if (!row.chargeCategory && row.unitcost){ - if (!billingHelper.supportsCustomUnitCost(row.chargeId)) - { - EHR.Server.Utils.addError(scriptErrors, 'unitCost', 'This type of charge does not support a custom unit cost. You should leave this blank and it will be automatically calculated.', 'WARN'); - } - } + // if (!row.chargeCategory && row.unitcost){ + // if (!billingHelper.supportsCustomUnitCost(row.chargeId)) + // { + // EHR.Server.Utils.addError(scriptErrors, 'unitCost', 'This type of charge does not support a custom unit cost. You should leave this blank and it will be automatically calculated.', 'WARN'); + // } + // } if (!row.Id){ if (!billingHelper.supportsBlankAnimal(row.chargeId)) diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql index 1de149355..d515867fb 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql @@ -4,6 +4,12 @@ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 */ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + SELECT mc.Id, mc.date, @@ -12,7 +18,30 @@ SELECT mc.chargeId, mc.item, mc.quantity, - mc.unitCost, + round(CAST(CASE + --order of priority for unit cost: + --project-level exemption: pay this value + WHEN (e.unitCost IS NOT NULL) THEN e.unitCost + --project-level multiplier: multiply NIH rate by this value + WHEN (pm.multiplier IS NOT NULL AND cr.unitCost IS NOT NULL) THEN (cr.unitCost * pm.multiplier) + --if there is not a known rate, we dont know what do to + WHEN (cr.unitCost IS NULL) THEN null + --for non-OGA aliases, we always use the NIH rate + WHEN (alias.category IS NOT NULL AND alias.category != 'OGA') THEN cr.unitCost + --if we dont know the aliasType, we also dont know what do to + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND mc.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN + ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) + + --remove subsidy only + WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) + + --raise F&A only + --WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND mc.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND mc.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) + --the NIH rate + ELSE cr.unitCost + END AS DOUBLE), 2) as unitCost, + --mc.unitCost, mc.category, mc.chargeCategory, mc.invoicedItemId, @@ -24,4 +53,38 @@ SELECT mc.invoiceId, mc.taskid, -FROM onprc_billing.miscCharges mc \ No newline at end of file +FROM onprc_billing.miscCharges mc + +LEFT JOIN onprc_billing_public.chargeRates cr ON ( + CAST(mc.date AS DATE) >= CAST(cr.startDate AS DATE) AND + (CAST(mc.date AS DATE) <= cr.enddateCoalesced OR cr.enddate IS NULL) AND + mc.chargeId = cr.chargeId +) + + LEFT JOIN onprc_billing_public.chargeRateExemptions e ON ( + CAST(mc.date AS DATE) >= CAST(e.startDate AS DATE) AND + (CAST(mc.date AS DATE) <= e.enddateCoalesced OR e.enddate IS NULL) AND + mc.chargeId = e.chargeId AND + mc.project = e.project +) + +LEFT JOIN onprc_billing_public.creditAccount ce ON ( + CAST(mc.date AS DATE) >= CAST(ce.startDate AS DATE) AND + (CAST(mc.date AS DATE) <= ce.enddateCoalesced OR ce.enddate IS NULL) AND + mc.chargeId = ce.chargeId +) + +LEFT JOIN onprc_billing_public.projectAccountHistory aliasAtTime ON ( + aliasAtTime.project = mc.project AND + aliasAtTime.startDate <= cast(mc.date as date) AND + aliasAtTime.endDate >= cast(mc.date as date) +) + +LEFT JOIN onprc_billing_public.aliases alias ON ( + aliasAtTime.account = alias.alias +) + +LEFT JOIN onprc_billing_public.projectMultipliers pm ON ( + CAST(mc.date AS DATE) >= CASt(pm.startDate AS DATE) AND + (CAST(mc.date AS DATE) <= pm.enddateCoalesced OR pm.enddate IS NULL) AND + alias.alias = pm.account) \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql index f8813240b..cd6d17fd6 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql @@ -1,11 +1,3 @@ -/* - * Copyright (c) 2013 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - --- NOTE: this query provides the raw data used in most of billing *Rates.sql queries. The goal is to have a single implementation of the --- process to assign rates and accounts to the raw charges. SELECT p.Id, p.date, @@ -19,6 +11,7 @@ SELECT round(CAST(CASE --order of priority for unit cost: --if this row specifies a unit cost, like an adjustment, defer to that. this is unique to miscCharges + --this occurs when the rate is a vairable rate or a reversal where an negative number is entered WHEN (p.unitCost IS NOT NULL) THEN p.unitCost --project-level exemption: pay this value WHEN (e.unitCost IS NOT NULL) THEN e.unitCost @@ -30,12 +23,12 @@ SELECT WHEN (alias.category IS NOT NULL AND alias.category != 'OGA') THEN cr.unitCost --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null - --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + --remove both subsidy and raise F&A if needed + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) - --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + --raise F&A on ly + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) --the NIH rate ELSE cr.unitCost END AS DOUBLE), 2) as unitCost, diff --git a/onprc_billing/resources/queries/onprc_billing/perDiemRates.sql b/onprc_billing/resources/queries/onprc_billing/perDiemRates.sql index a49212cab..d7a74ce5a 100644 --- a/onprc_billing/resources/queries/onprc_billing/perDiemRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/perDiemRates.sql @@ -47,12 +47,16 @@ SELECT --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN + ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) + --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) + --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) - --the NIH rate + --WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) + --the NIH rate ELSE cr.unitCost END AS DOUBLE), 2) as unitCost, cr.unitCost as nihRate, diff --git a/onprc_billing/resources/queries/onprc_billing/procedureFeeRates.sql b/onprc_billing/resources/queries/onprc_billing/procedureFeeRates.sql index 41fe00395..6611b4d9b 100644 --- a/onprc_billing/resources/queries/onprc_billing/procedureFeeRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/procedureFeeRates.sql @@ -41,12 +41,16 @@ SELECT --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN + ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) + --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) + --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) - --the NIH rate + --WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) + --the NIH rate ELSE cr.unitCost END AS DOUBLE), 2) as unitCost, cr.unitCost as nihRate, @@ -204,4 +208,4 @@ SELECT FROM onprc_billing.miscChargesFeeRateData mc WHERE cast(mc.billingDate as date) >= CAST(StartDate as date) AND cast(mc.billingDate as date) <= CAST(EndDate as date) -AND mc.category IN ('Surgical Procedure', 'Clinical Procedure', 'Surgery', 'Pathology') +AND mc.category IN ('Surgical Procedure', 'Clinical Procedure', 'Surgery', 'Pathology') \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/slaPerDiemRates.sql b/onprc_billing/resources/queries/onprc_billing/slaPerDiemRates.sql index e20ffb0bf..ae22b9ffc 100644 --- a/onprc_billing/resources/queries/onprc_billing/slaPerDiemRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/slaPerDiemRates.sql @@ -40,13 +40,17 @@ SELECT WHEN (alias.category IS NOT NULL AND alias.category != 'OGA') THEN cr.unitCost --if we dont know the aliasType, we also dont know what do to WHEN (alias.aliasType.aliasType IS NULL) THEN null - --remove both subsidy and raise F&A if needed - WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + --remove both subsidy and raise F&A if needed------- Changed by Kollil on 5/19/17 + WHEN (alias.aliasType.removeSubsidy = true AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN ((cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN + ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) / (1 + alias.faRate)))) ELSE 1 END)) + --remove subsidy only WHEN (alias.aliasType.removeSubsidy = true AND alias.aliasType.canRaiseFA = false) THEN (cr.unitCost / (1 - COALESCE(cr.subsidy, 0))) + --raise F&A only - WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) - --the NIH rate + --WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN (1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE) - alias.faRate)) ELSE 1 END)) + WHEN (alias.aliasType.removeSubsidy = false AND (alias.aliasType.canRaiseFA = true AND p.chargeId.canRaiseFA = true)) THEN (cr.unitCost * (CASE WHEN (alias.faRate IS NOT NULL AND alias.faRate < CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)) THEN ((1 + (CAST(javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.BASE_SUBSIDY') AS DOUBLE)))/(1+ alias.faRate)) ELSE 1 END)) + --the NIH rate ELSE cr.unitCost END AS DOUBLE), 2) as unitCost, cr.unitCost as nihRate, @@ -55,7 +59,7 @@ SELECT cast(ce.account as varchar(200)) as creditAccount, ce.rowid as creditAccountId, - coalesce(alias.investigatorId, p.project.investigatorId) as investigatorId, + alias.investigatorId as investigatorId, CASE WHEN e.unitCost IS NOT NULL THEN 'Y' WHEN pm.multiplier IS NOT NULL THEN ('Multiplier: ' || CAST(pm.multiplier AS varchar(100))) @@ -93,7 +97,7 @@ SELECT ELSE null END as isExpiredAccount, CASE WHEN (TIMESTAMPDIFF('SQL_TSI_DAY', p.date, curdate()) > 45) THEN 'Y' ELSE null END as isOldCharge, - p.project.account as currentActiveAlias + p.project as currentActiveAlias FROM onprc_billing.slaPerDiems p diff --git a/onprc_billing/resources/schemas/onprc_billing.xml b/onprc_billing/resources/schemas/onprc_billing.xml index 6cae5f0f0..bf0d85a0a 100644 --- a/onprc_billing/resources/schemas/onprc_billing.xml +++ b/onprc_billing/resources/schemas/onprc_billing.xml @@ -18,7 +18,7 @@ End Date false - yyyy-MM-dd + Date @@ -52,7 +52,7 @@ End Date false - yyyy-MM-dd + Date @@ -118,11 +118,12 @@ Start Date + Date End Date false - yyyy-MM-dd + Date @@ -156,6 +157,7 @@ Transaction Date + Date Item @@ -290,7 +292,9 @@ true - + + Date + @@ -321,16 +325,18 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date - + + Date + @@ -347,7 +353,7 @@ Date of Charge This column typically refers to the date the charge took place (ie. date blood was drawn). This differs from the column labeled Date Charge Created, which refers to the date the charge was actually entered into the system. This column is used in the IBS sheet; however, it is not used to determine which billing period the item falls into. - yyyy-MM-dd + Date @@ -569,12 +575,12 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date @@ -625,12 +631,12 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date @@ -650,10 +656,12 @@ Billing Period Start + Date false Billing Period End + Date false @@ -751,12 +759,12 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date @@ -853,7 +861,7 @@ End Date true - yyyy-MM-dd + Date Fiscal Authority @@ -876,9 +884,11 @@ Budget Start Date + Date Budget End Date + Date Comment @@ -941,12 +951,12 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date @@ -993,12 +1003,12 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date @@ -1020,14 +1030,14 @@ Start Date This column refers to the date that this alias was first associated with this project. In other words, this alias is the active alias for the project between the dates listed. - yyyy-MM-dd + Date false End Date This column refers to the date that this alias is no longer associated with this project. In other words, this alias is the active alias for the project between the dates listed. true - yyyy-MM-dd + Date @@ -1087,9 +1097,11 @@ Current Budget Start Date + Date Current Budget End Date + Date Fiscal Authority @@ -1155,9 +1167,11 @@ Alias Start Date + Date Alias End Date + Date F&A Rate @@ -1209,7 +1223,7 @@ End Date - yyyy-MM-dd + Date @@ -1256,12 +1270,12 @@ Start Date false - yyyy-MM-dd + Date End Date false - yyyy-MM-dd + Date @@ -1485,4 +1499,35 @@ + + org.labkey.ehr.table.DefaultEHRCustomizer + DETAILED + Annual Rate Change + + + Row Id + + + Billing Year + + + + Inflation Rate + 0.0000 + false + + + false + Start Date + + + false + End Date + + + + + + +
\ No newline at end of file diff --git a/onprc_billing/resources/scripts/onprc_billing/billing_triggers.js b/onprc_billing/resources/scripts/onprc_billing/billing_triggers.js index e9c11453f..5dee9574d 100644 --- a/onprc_billing/resources/scripts/onprc_billing/billing_triggers.js +++ b/onprc_billing/resources/scripts/onprc_billing/billing_triggers.js @@ -100,19 +100,19 @@ exports.init = function(EHR){ } }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'Clinical Encounters', function(helper, scriptErrors, row, oldRow){ + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'encounters', function(helper, scriptErrors, row, oldRow){ if (row && oldRow){ processUpdate(helper, 'encounters', ['project', 'Id', 'date', 'chargetype', 'procedureid'], row, oldRow); } }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'Clinpath Runs', function(helper, scriptErrors, row, oldRow){ + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'clinpathruns', function(helper, scriptErrors, row, oldRow){ if (row && oldRow){ processUpdate(helper, 'clinpathRuns', ['project', 'Id', 'date', 'chargetype', 'servicerequested'], row, oldRow); } }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'Blood Draws', function(helper, scriptErrors, row, oldRow){ + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'blood', function(helper, scriptErrors, row, oldRow){ console.log('inspecting blood draws record for billing audit'); if (row && oldRow){ diff --git a/onprc_billing/resources/views/invoiceRunDetails.html b/onprc_billing/resources/views/invoiceRunDetails.html index a7b9e5919..01d2955bf 100644 --- a/onprc_billing/resources/views/invoiceRunDetails.html +++ b/onprc_billing/resources/views/invoiceRunDetails.html @@ -161,9 +161,12 @@ {name: 'Download IBS Spreadsheet (PDAR - Leases)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'PDAR', 'query.category~in': 'Lease Fees;Lease Setup Fees;Lease Fee Adjustment'})}, {name: 'Download IBS Spreadsheet (PDAR - Per Diems)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'PDAR', 'query.category~eq': 'Animal Per Diem'})}, {name: 'Download IBS Spreadsheet (PDAR - Other)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'PDAR', 'query.category~notin': 'Animal Per Diem;Lease Fees;Lease Setup Fees;Lease Fee Adjustment'})}, + {name: 'Download IBS Spreadsheet (PMIC)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'PMIC', 'query.category~in': 'PMIC'})}, {name: 'Download IBS Spreadsheet (PSURG)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'PSURG'})}, + {name: 'Download IBS Spreadsheet (PVIRO)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'PVIRO'})}, + {name: 'Download IBS Spreadsheet (SLAU)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~eq': 'SLAU'})}, - {name: 'Download IBS Spreadsheet (Other)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~notin': 'PDAR;PSURG;SLAU'})} + {name: 'Download IBS Spreadsheet (Other)', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'chargesIBS', 'query.invoiceId~eq': this.invoiceRunId, 'query.servicecenter~notin': 'PDAR;PSURG;SLAU;PVIRO;PMIC'})}, ] },{ header: 'Charge Calculations For This Billing Period', diff --git a/onprc_billing/resources/web/onprc_billing/panel/ChargesInstructionPanel.js b/onprc_billing/resources/web/onprc_billing/panel/ChargesInstructionPanel.js index f433b4655..5d1a2e893 100644 --- a/onprc_billing/resources/web/onprc_billing/panel/ChargesInstructionPanel.js +++ b/onprc_billing/resources/web/onprc_billing/panel/ChargesInstructionPanel.js @@ -11,7 +11,9 @@ Ext4.define('ONPRC_Billing.panel.ChargesInstructionPanel', { items: [{ html: 'This form allows authorized users to enter new charges. This should only be used for changes that are not automatically calculated from the animal record. ' + '

' + - 'Important: The vast majority of the time, you should leave unit cost blank. It will be calculated based on standard rates (at the time of the charge), and based on known exemptions. This field will only be editable if the item you selected supports variable unit cost.', + 'Important: The vast majority of the time, you should leave unit cost blank. It will be calculated based on standard rates (at the time of the charge), and based on known exemptions. This field will only be editable if the item you selected supports variable unit cost.' + + '

' + + 'Note: Recent changes to the property settings now allows you to enter either the Center Project, or the Alias number.', style: 'padding: 5px;' }] }) diff --git a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java index aff7da8c5..bcc0c4f7c 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java +++ b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java @@ -42,6 +42,8 @@ import org.labkey.onprc_billing.button.ProjectEditButton; import org.labkey.onprc_billing.dataentry.ChargesAdvancedFormType; import org.labkey.onprc_billing.dataentry.ChargesFormType; +//import org.labkey.onprc_billing.dataentry.ChargesVirologyCoreFormType; +import org.labkey.onprc_billing.dataentry.ChargesVirologyCoreFormType; import org.labkey.onprc_billing.dataentry.ReversalFormType; import org.labkey.onprc_billing.notification.BillingValidationNotification; import org.labkey.onprc_billing.notification.DCMFinanceNotification; @@ -75,7 +77,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 12.372; + return 17.502; } @Override @@ -117,6 +119,9 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext) EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ChargesFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ReversalFormType.class, this)); + //Added: 5/6/2018 Kollil + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ChargesVirologyCoreFormType.class, this)); + //NOTE: not really being used, so have disabled //Resource billingTriggers = getModuleResource("/scripts/onprc_billing/billing_triggers.js"); //assert billingTriggers != null; diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormSection.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormSection.java index a736fe454..0c4ccdac1 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormSection.java +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormSection.java @@ -18,8 +18,11 @@ import org.labkey.api.ehr.EHRService; import org.labkey.api.ehr.dataentry.SimpleFormSection; import org.labkey.api.view.template.ClientDependency; +import org.json.JSONObject; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; import java.util.Collections; +import java.util.List; /** * User: bimber @@ -40,4 +43,24 @@ public ChargesFormSection(EHRService.FORM_SECTION_LOCATION location) setClientStoreClass("EHR.data.MiscChargesClientStore"); addClientDependency(ClientDependency.supplierFromPath("ehr/data/MiscChargesClientStore.js")); } + // Added: 3-8-2018 R.Blasa + @Override + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { + JSONObject jsonObject = super.toJSON(ctx, includeFormElements); + jsonObject.put("topAndBottomButtons", true); + return jsonObject; + } + + + + @Override + public List getTbarButtons() + { + List defaultButtons = super.getTbarButtons(); + defaultButtons.remove("ADDANIMALS"); + defaultButtons.add(0, "ADDANIMALST"); + + return defaultButtons; + } } diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java index a97bbc4b5..b493659a9 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java @@ -6,7 +6,11 @@ import org.labkey.api.ehr.dataentry.TaskForm; import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.module.Module; +import org.labkey.api.security.Group; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; import java.util.Arrays; import java.util.List; @@ -41,4 +45,16 @@ protected List getMoreActionButtonConfigs() return defaultButtons; } + + //Added: 8-22-2018 R.Blasa + @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "SLA Users", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + return super.isVisible(); + } } diff --git a/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java b/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java index 99d2bfd3f..9c2684a40 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java +++ b/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java @@ -21,6 +21,8 @@ import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.CompareType; import org.labkey.api.data.Container; +import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.ContainerFilterable; import org.labkey.api.data.Results; import org.labkey.api.data.ResultsImpl; import org.labkey.api.data.SQLFragment; @@ -189,6 +191,10 @@ public String getMessageBodyHTML(Container c, User u) getExpiredCreditAliases(ehrContainer, u, msg); getCreditAliasesDisabled(ehrContainer, u, msg); chargesMissingRates(financeContainer, u, msg); + + //Added by Kollil + getSchedulerAliases(ehrContainer, u, msg); + surgeriesNotBilled(ehrContainer, u, start, endDate, msg); simpleAlert(financeContainer, u , msg, "onprc_billing", "invalidChargeRateEntries", " charge rate records with invalid or overlapping intervals. This indicates a problem with how the records are setup in the system and may cause problems with the billing calculation."); simpleAlert(financeContainer, u , msg, "onprc_billing", "invalidChargeRateExemptionEntries", " charge rate exemptions with invalid or overlapping intervals. This indicates a problem with how the records are setup in the system and may cause problems with the billing calculation."); @@ -789,4 +795,28 @@ private void getProjectsNotActive(Container c, User u, StringBuilder msg) msg.append("
"); } } + + private void getSchedulerAliases(Container c, User u, StringBuilder msg) + { + + if (QueryService.get().getUserSchema(u, c, "extscheduler") == null) + { + msg.append("Warning: the extscheduler schema has not been enabled in this folder, so the alias alert cannot run


"); + return; + } + + TableInfo ti = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("SchedulerAliases"); + ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Alias"), null, CompareType.NONBLANK); + TableSelector ts = new TableSelector(ti, filter, null); + long count = ts.getRowCount(); + if (count > 0) + { + msg.append("Warning: In Resource Scheduler, there are " + count + " invalid Aliases.

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


"); + } + + } + } diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml index 253897053..68219dd34 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml @@ -8,45 +8,48 @@ - + Current Year $#,##0.00 + - YR58: 5/1/17 to 4/30/18 - $#,##0.00 - - - YR59: 5/1/18 to 4/30/19 - $#,##0.00 - - YR60: 5/1/19 to 4/30/20 $#,##0.00 - + YR61: 5/1/20 to 4/30/21 $#,##0.00 - + YR62: 5/1/21 to 4/30/22 $#,##0.00 - + YR63: 5/1/22 to 4/30/23 $#,##0.00 - + YR64: 5/1/23 to 4/30/24 $#,##0.00 - + YR65: 5/1/24 to 4/30/25 $#,##0.00 + + YR66: 5/1/25 to 4/30/26 + $#,##0.00 + + + + + + + Posted Date MM/dd/yyyy diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml index f8fb313a4..1e4f7f75a 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml @@ -6,54 +6,63 @@ NIH Project Rate Config - - - - - Current Year - $#,##0.00 - + + + + Current Year + $#,##0.00 + - - 5/1/2017 to 4/30/2018 - $###0.00 - - - 5/1/2018 to 4/30/2019 - $###0.00 - - - 5/1/2019 to 4/30/2020 - $###0.00 - - - 5/1/2020 to 4/30/2021 - $###0.00 - - - 5/1/2021 to 4/30/2022 - $###0.00 - - - 5/1/2022 to 4/30/2023 - $###0.00 - - - 5/1/2023 to 4/30/2024 - $###0.00 - + + + + + + YR59: 5/1/18 to 4/30/19 + $#,##0.00 + + + YR60: 5/1/19 to 4/30/20 + $#,##0.00 + + + YR61: 5/1/20 to 4/30/21 + $#,##0.00 + + + YR62: 5/1/21 to 4/30/22 + $#,##0.00 + + + YR63: 5/1/22 to 4/30/23 + $#,##0.00 + + + YR64: 5/1/23 to 4/30/24 + $#,##0.00 + - - 5/1/2024 to 4/30/2025 - $###0.00 - + + YR65: 5/1/24 to 4/30/25 + $#,##0.00 + - - Posted Date - MM/dd/yyyy - + + YR66: 5/1/25 to 4/30/26 + $#,##0.00 + - + + + + + + + Posted Date + MM/dd/yyyy + + + diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml index 2cb976f4c..0dd30378d 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml @@ -8,45 +8,55 @@ - + Current Year $#,##0.00 + + + + - YR58: 5/1/17 to 4/30/18 + YR59: 5/1/18 to 4/30/19 $#,##0.00 - YR59: 5/1/18 to 4/30/19 + YR60: 5/1/19 to 4/30/20 $#,##0.00 - YR60: 5/1/19 to 4/30/20 + YR61: 5/1/20 to 4/30/21 $#,##0.00 - YR61: 5/1/20 to 4/30/21 + YR62: 5/1/21 to 4/30/22 $#,##0.00 - YR62: 5/1/21 to 4/30/22 + YR63: 5/1/22 to 4/30/23 $#,##0.00 - YR63: 5/1/22 to 4/30/23 + YR64: 5/1/23 to 4/30/24 $#,##0.00 + - YR64: 5/1/23 to 4/30/24 + YR65: 5/1/24 to 4/30/25 $#,##0.00 - YR65: 5/1/24 to 4/30/25 + YR66: 5/1/25 to 4/30/26 $#,##0.00 + + + + + Posted Date MM/dd/yyyy diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet/.qview.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet/.qview.xml index 1cd7ebb69..0bcc0e520 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet/.qview.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet/.qview.xml @@ -2,49 +2,50 @@ - + - + + - + - + - + - + - + - + - + diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml index b373a5bfb..fb8009dc8 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml @@ -8,44 +8,51 @@ - + Current Year $#,##0.00 + + + + + - YR58: 5/1/17 to 4/30/18 + YR60: 5/1/19 to 4/30/20 $#,##0.00 - YR59: 5/1/18 to 4/30/19 + YR61: 5/1/20 to 4/30/21 $#,##0.00 - YR60: 5/1/19 to 4/30/20 + YR62: 5/1/21 to 4/30/22 $#,##0.00 - YR61: 5/1/20 to 4/30/21 + YR63: 5/1/22 to 4/30/23 $#,##0.00 - YR62: 5/1/21 to 4/30/22 + YR64: 5/1/23 to 4/30/24 $#,##0.00 + - YR63: 5/1/22 to 4/30/23 + YR65: 5/1/24 to 4/30/25 $#,##0.00 + - YR64: 5/1/23 to 4/30/24 + YR66: 5/1/25 to 4/30/26 $#,##0.00 - - YR65: 5/1/24 to 4/30/25 - $#,##0.00 - + Posted Date diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA/.qview.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA/.qview.xml index 27e26da8a..784e8e236 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA/.qview.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA/.qview.xml @@ -2,51 +2,48 @@ - + - - - - - - + + + - + - + - + - + - + + diff --git a/onprc_ehr/resources/etls/AvailableBlood.xml b/onprc_ehr/resources/etls/AvailableBlood.xml new file mode 100644 index 000000000..21a46893f --- /dev/null +++ b/onprc_ehr/resources/etls/AvailableBlood.xml @@ -0,0 +1,36 @@ + + + + + AvailableBloodVolume + + Transfers from the Available Blood Volume Calculation in labkeyPublic.onprc_ehr to Production + + + + + + + + Truncate and Populate Available Blood Data + + + + + + + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/etls/HarvestToPrime_Process.xml b/onprc_ehr/resources/etls/HarvestToPrime_Process.xml new file mode 100644 index 000000000..c95ca9040 --- /dev/null +++ b/onprc_ehr/resources/etls/HarvestToPrime_Process.xml @@ -0,0 +1,73 @@ + + + + + Harvest_To_Prime_Process + + Transfers LIS schema temp tables into study dataset lab values + + + + + + Runs a stored procedure that generates lab values + + + + + + + + Transfer to EHR Tasks + + + + + + + + + + Transfer to ClinpathRuns + + + + + + + + + + Transfer to ChemistryResults + + + + + + + + + + Transfer to HematologyResults + + + + + + + + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/etls/TreatmentToDrug.xml b/onprc_ehr/resources/etls/TreatmentToDrug.xml new file mode 100644 index 000000000..c5df5d329 --- /dev/null +++ b/onprc_ehr/resources/etls/TreatmentToDrug.xml @@ -0,0 +1,14 @@ + + + TreatmentToDrug + Transfers from the treatmentProcessing table in Study to the Drug table in Study + + + Transfer to Drug Table + + + + + + + diff --git a/onprc_ehr/resources/etls/eIACUCToPrimce.xml b/onprc_ehr/resources/etls/eIACUCToPrimce.xml new file mode 100644 index 000000000..48f787146 --- /dev/null +++ b/onprc_ehr/resources/etls/eIACUCToPrimce.xml @@ -0,0 +1,111 @@ + + + + + eiACUCtoPrime + + Transfers from the eIACUC Import tables to the Prime tables in ONPRC_EHRy + + + + + + + + Transfer to eIACUC Animal Groups + + + + + + + + + + Transfer to IBX Numbers + + + + + + + + + + Transfer to Non Surgical Procedures + + + + + + + + + + Transfer to Protocols + + + + + + + + + + + Transfer to Surgical Procedures + + + + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/etls/rateChangeprocess.xml b/onprc_ehr/resources/etls/rateChangeprocess.xml new file mode 100644 index 000000000..119af1439 --- /dev/null +++ b/onprc_ehr/resources/etls/rateChangeprocess.xml @@ -0,0 +1,27 @@ + + + + + ratechangeProcess + + Updates the Rate Sheets for Investigators in the Billing Folder + + + + + Runs a stored procedure to update the Rate Sheet for Public Rate Projections. + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/queries/ehr/SnomedBySetSearch.sql b/onprc_ehr/resources/queries/ehr/SnomedBySetSearch.sql new file mode 100644 index 000000000..bb81c25ad --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/SnomedBySetSearch.sql @@ -0,0 +1,75 @@ + +---- Created: 12-15-2017 R.Blasa + +PARAMETERS(SNOMEDCODE VARCHAR, STARTDATE TIMESTAMP, ENDDATE TIMESTAMP) + + +SELECT + t1.Id, + e.date, + e.caseno, + t1.type, + t1.sort_order, + t1.codes, + t1.codesMeaning, + t1.meaning, + e.taskid +FROM ( +SELECT + +e.Id, +e.recordid, +e.sort_order, +e.parentid, +group_concat(DISTINCT e.type) as type, +group_concat(e.codeWithSort, chr(10)) as codes, +group_concat(e.codeMeaning, chr(10)) as codesMeaning, +group_concat(e.meaning, chr(10)) as meaning + +FROM ( + +SELECT + pd.Id, + pd.date, + 'Diagnosis' as type, + --e.objectid, + --e.caseno, + s.recordid, + pd.sort_order, + pd.parentid, + cast(s.codeWithSort as varchar) as codeWithSort, + s.code, + sno.meaning, + cast((cast(s.sort as varchar(10)) || cast(': ' as varchar(2)) || sno.meaning || ' (' || s.code || ')') as varchar(2000)) as codeMeaning + +FROM ehr.snomed_tags s +JOIN study.pathologyDiagnoses pd ON (s.recordid = pd.objectid And s.code.code = rtrim(snomedCode)) +JOIN ehr_lookups.snomed sno ON (s.code = sno.code) + + UNION ALL + +SELECT + pd.Id, + pd.date, + 'Histology' as type, + --e.objectid, + --e.caseno, + s.recordid, + pd.formSort as sort_order, + pd.parentid, + cast(s.codeWithSort as varchar) as codeWithSort, + s.code, + sno.meaning, + cast((cast(s.sort as varchar(10)) || cast(': ' as varchar(2)) || sno.meaning || ' (' || s.code || ')') as varchar(2000)) as codeMeaning + +FROM ehr.snomed_tags s +JOIN study.histology pd ON (s.recordid = pd.objectid And s.code.code = rtrim(snomedCode)) +JOIN ehr_lookups.snomed sno ON (s.code = sno.code) + +) e + +GROUP BY e.Id, e.recordid, e.parentid, e.sort_order + +) t1 + +JOIN study.encounters e ON (e.Id = t1.Id AND e.objectid = t1.parentid And (e.date < ENDDATE and e.date >= STARTDATE)) diff --git a/onprc_ehr/resources/queries/ehr/SnomedBySetSearch/.qview.xml b/onprc_ehr/resources/queries/ehr/SnomedBySetSearch/.qview.xml new file mode 100644 index 000000000..44c78d360 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/SnomedBySetSearch/.qview.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/ehr/project_active.sql b/onprc_ehr/resources/queries/ehr/project_active.sql new file mode 100644 index 000000000..f2875619e --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/project_active.sql @@ -0,0 +1,13 @@ +SELECT project.name, +project.protocol, +project.investigatorId, +project.title, +project.use_category, +project.startdate, +project.enddate, +project.shortname, +project.container, +project.displayName, +project.account +FROM project +where (enddate is null or enddate >= Now()) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/ehr/requests.query.xml b/onprc_ehr/resources/queries/ehr/requests.query.xml new file mode 100644 index 000000000..efe747489 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/requests.query.xml @@ -0,0 +1,142 @@ + + + + + org.labkey.ehr.table.DefaultEHRCustomizer + /ehr/requestDetails.view?formtype=${formtype}&requestid=${requestid} + + + + + RowId + requestid + + + Request Id + true + true + /ehr/requestDetails.view?formtype=${formtype}&requestid=${requestid} + + + /ehr/requestDetails.view?formtype=${formtype}&requestid=${requestid} + + + true + true + Request Id + + + Request Type + + ehr + formtypes + type + + + + Created By + + core + users + userid + + + + First Contact + + core + PrincipalsWithoutAdmin + userid + + + + Second Contact + + + + + + + + Third Contact + + + + + + + + PI + + + + ehr_lookups + request_priority + priority + + + + Lab Phone # + + + Created + yyyy-MM-dd HH:mm + + + Modified By + + + Modified + + + Date Requested + + + true + + + true + Status + + study + qcstate + rowid + + 200 + + + 200 + + + textarea + + + + + + + + + + Views + + + Export + + + Print + + + + + + Page Size + + + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/ehr/requests/.qview.xml b/onprc_ehr/resources/queries/ehr/requests/.qview.xml new file mode 100644 index 000000000..f4a3f11f0 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/requests/.qview.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/ehr/snomed_tags.js b/onprc_ehr/resources/queries/ehr/snomed_tags.js new file mode 100644 index 000000000..aa25d9880 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/snomed_tags.js @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2011-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +require("ehr/triggers").initScript(this); diff --git a/onprc_ehr/resources/queries/onprc_ehr/ChemistryDept.sql b/onprc_ehr/resources/queries/onprc_ehr/ChemistryDept.sql new file mode 100644 index 000000000..743a99914 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/ChemistryDept.sql @@ -0,0 +1,3 @@ +select value, sort_order from sla.Reference_Data +where columnName = 'BiochemistryDept' +And endDate is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.query.xml b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.query.xml new file mode 100644 index 000000000..c2e807c6a --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.query.xml @@ -0,0 +1,57 @@ + + + + + Necropsy Task + + + Task ID + /ehr/dataEntryForm.view?formType=${formtype}&taskid=${taskid} + + + Title + /ehr/dataEntryForm.view?formType=${formtype}&taskid=${taskid} + + + Procedure Name + + + Investigator + + + Assigned To + true + + core + PrincipalsWithoutAdmin + UserId + + + + Due Date + true + yyyy-MM-dd HH:mm + + + Created By + + core + users + userid + + + + + false + true + Status + 50 + + + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.sql b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.sql new file mode 100644 index 000000000..be3101474 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask.sql @@ -0,0 +1,22 @@ +-- Created: 3-30-2017 R.Blasa + + +SELECT +t.taskid, +t.title, +g.procedureid.name as ProcedureName, +g.project.InvestigatorId.lastname as Investigator, +t.assignedto, +t.duedate, +t.createdby, +t.created, +t.qcstate, +t.formtype + + +FROM ehr.tasks t + Left join study.encounters g on (t.taskid = g.taskid And g.type = 'Necropsy') + + + + diff --git a/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/.qview.xml new file mode 100644 index 000000000..b8e232b24 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/.qview.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/ActiveTasks.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/ActiveTasks.qview.xml new file mode 100644 index 000000000..f8b08e55b --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NecropsyTask/ActiveTasks.qview.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/PairingEndType.sql b/onprc_ehr/resources/queries/onprc_ehr/PairingEndType.sql new file mode 100644 index 000000000..3c7ec649c --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/PairingEndType.sql @@ -0,0 +1,7 @@ + +-- Created: 6-20-2018 R.Blasa + + +select value, sort_order from sla.Reference_Data +where columnName = 'PairingEndtype' +And endDate is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/PairingStartType.sql b/onprc_ehr/resources/queries/onprc_ehr/PairingStartType.sql new file mode 100644 index 000000000..5aa0add81 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/PairingStartType.sql @@ -0,0 +1,5 @@ +-- Created: 6-20-2018 R.Blasa + +select value, sort_order from sla.Reference_Data +where columnName = 'PairingStarttype' +And endDate is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/my_tasks.sql b/onprc_ehr/resources/queries/onprc_ehr/my_tasks.sql new file mode 100644 index 000000000..22a600958 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/my_tasks.sql @@ -0,0 +1,24 @@ +-- Created: 3-24-2017 R.Blasa + + +SELECT +t.taskid, +t.updateTitle, +t.category, +t.title, +t.formtype, +t.qcstate, +t.assignedto, +t.duedate, +t.requestid, +t.datecompleted, +t.createdby, +t.created, +t.description, +g.procedureid.name as ProcedureName, +g.project.InvestigatorId.lastname as Investigator +FROM ehr.tasks t + Left join study.encounters g on (t.taskid = g.taskid And g.type = 'Necropsy') + +WHERE ISMEMBEROF(t.assignedto) + diff --git a/onprc_ehr/resources/queries/onprc_ehr/my_tasks/.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/.qview.xml new file mode 100644 index 000000000..8fde9e2a7 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/.qview.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Active Tasks.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Active Tasks.qview.xml new file mode 100644 index 000000000..cd21c338e --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Active Tasks.qview.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Necropsies.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Necropsies.qview.xml new file mode 100644 index 000000000..70c2229cb --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Necropsies.qview.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Review Required.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Review Required.qview.xml new file mode 100644 index 000000000..74173fca0 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Review Required.qview.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Today.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Today.qview.xml new file mode 100644 index 000000000..4400e56bd --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/my_tasks/Today.qview.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/userNames.query.xml b/onprc_ehr/resources/queries/onprc_ehr/userNames.query.xml new file mode 100644 index 000000000..6543f0fe5 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/userNames.query.xml @@ -0,0 +1,14 @@ + + + + + DisplayName + + + true + + +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/userNames.sql b/onprc_ehr/resources/queries/onprc_ehr/userNames.sql new file mode 100644 index 000000000..f3ccc7b56 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/userNames.sql @@ -0,0 +1,8 @@ +SELECT + u.DisplayName, + 'u' as type, + u.FirstName, + u.LastName, + u.Active + +FROM onprc_ehr.usersActiveNames u \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/BCS_Recent_Score.sql b/onprc_ehr/resources/queries/study/BCS_Recent_Score.sql new file mode 100644 index 000000000..37ff7ed46 --- /dev/null +++ b/onprc_ehr/resources/queries/study/BCS_Recent_Score.sql @@ -0,0 +1,21 @@ +Select +c.id, +c.observation as score, +c.date, +c.created +From study.clinical_Observations c + +RIGHT JOIN + (Select + a.id, + MAX(CAST(a.date AS DATE)) as MaxDate + From study.clinical_Observations a + Where a.category = 'bcs' + And a.date > TIMESTAMPADD('SQL_TSI_MONTH', -18, Now()) + and a.observation is not null + --And a.id in ('30661', '16609') + Group by a.id -- , a.date + ) As d + +ON c.id = d.id And CAST(c.date AS DATE) = d.MaxDate +Where c.category = 'bcs' and c.id not like '[a-z]%' diff --git a/onprc_ehr/resources/queries/study/Birth.js b/onprc_ehr/resources/queries/study/Birth.js new file mode 100644 index 000000000..d937acc20 --- /dev/null +++ b/onprc_ehr/resources/queries/study/Birth.js @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2010-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created 3-3-2017 R.Blasa +require("ehr/triggers").initScript(this); + +function onInit(event, helper){ + helper.setScriptOptions({ + allowAnyId: true, + requiresStatusRecalc: true, + allowDeadIds: true, + skipIdFormatCheck: true, + skipHousingCheck: true, + announceAllModifiedParticipants: true + }); + + helper.decodeExtraContextProperty('birthsInTransaction'); +} + +function onUpsert(helper, scriptErrors, row, oldRow){ + if (row.weight && !row.wdate){ + EHR.Server.Utils.addError(scriptErrors, 'wdate', 'This field is required when supplying a weight', 'WARN'); + } + + if (!row.weight && row.wdate){ + EHR.Server.Utils.addError(scriptErrors, 'weight', 'This field is required when supplying a weight date', 'WARN'); + } + + // the highest error this can produce is WARN. therefore skip this check if we would ignore it anyway in order to save the overhead. + // this would normally occur when finalizing a form + if (!helper.isETL() && row.Id && row.weight && row.species && EHR.Server.Utils.shouldIncludeError('WARN', helper.getErrorThreshold(), helper)){ + var msg = helper.getJavaHelper().verifyWeightRange(row.Id, row.weight, row.species); + if (msg != null){ + EHR.Server.Utils.addError(scriptErrors, 'weight', msg, 'WARN'); + } + } +} + +EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'Birth', function(scriptErrors, helper, row, oldRow) +{ + // skip normal birth records process when birth condition has a value of Fetus + if (row.Id && row.birth_condition == 'Fetus - Prenatal') + { + var obj = { + Id: row.Id, + birth: row.date, + date: row.date, + calculated_status: 'Fetus' + }; + + + helper.getJavaHelper().createDemographicsRecord(row.Id, obj); + } + + else + { + var isLiving = EHR.Server.Utils.isLiveBirth(row.birth_condition); + if (isLiving) + { + helper.registerLiveBirth(row.Id, row.date); + } + + if (!helper.isETL()) + { + //if a weight is provided, we insert into the weight table: + if (row.weight && row.wdate) + { + helper.getJavaHelper().insertWeight(row.Id, row.wdate, row.weight); + } + + //if room provided, we insert into housing. if this animal already has an active housing record, skip + //Modified: 5-4-2018 R. Blasa Housing (This being handled by onprc_trigger.js) + // if (row.room && row.Id && row.date) + // { + // console.log("Birth js file") + // // helper.getJavaHelper().createHousingRecord(row.Id, row.date, (isLiving ? null : row.date), row.room, (row.cage || null),null); + // } + + if (!helper.isGeneratedByServer()) + { + var obj = { + Id: row.Id, + gender: row.gender, + dam: row.dam, + sire: row.sire, + origin: row.origin, + birth: row.date, + date: row.date, + calculated_status: isLiving ? 'Alive' : 'Dead' + + }; + + //NOTE: the follow is designed to allow the table to either have physical columns for species/origin, or do display the demographics values. in the latter case, editing the form field will act to update the demographics record + if (row.species || row['Id/demographics/species']) + { + obj.species = row.species || row['Id/demographics/species']; + } + + if (row.geographic_origin || row['Id/demographics/geographic_origin']) + { + obj.geographic_origin = row.geographic_origin || row['Id/demographics/geographic_origin']; + } + + //find dam, if provided + if (row.dam && !obj.geographic_origin) + { + obj.geographic_origin = helper.getJavaHelper().getGeographicOrigin(row.dam); + } + + if (row.dam && !obj.species) + { + obj.species = helper.getJavaHelper().getSpecies(row.dam); + } + + if (!isLiving) + { + obj.death = row.date; + } + + //if not already present, we insert into demographics + helper.getJavaHelper().createDemographicsRecord(row.Id, obj); + } + } + } + +}); \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.query.xml b/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.query.xml new file mode 100644 index 000000000..a3a7295a2 --- /dev/null +++ b/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.query.xml @@ -0,0 +1,15 @@ + + + + + Birth Locations with Mismatched Initial Housing Record + + + + + ehr.context + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.sql b/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.sql new file mode 100644 index 000000000..a4c9af46f --- /dev/null +++ b/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch.sql @@ -0,0 +1,8 @@ +select k.Id,K.date,k.room,k.cage,s.room as "Housing Room",s.cage as "Housing Cage" + +from study.birth k, study.Housing s +where ((s.reason = 'initialTransfer' or s.reason is null) and s.reason <> 'unknown') +and (s.room.room <> k.room.room and (s.cage <> k.cage or s.cage is null and k.cage is null)) +and (k.Id = s.participantid) +and k.qcstate.publicdata = true + diff --git a/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch/.qview.xml b/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch/.qview.xml new file mode 100644 index 000000000..a6e973473 --- /dev/null +++ b/onprc_ehr/resources/queries/study/BirthInitialHousingMismatch/.qview.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/BloodCalcBCS.sql b/onprc_ehr/resources/queries/study/BloodCalcBCS.sql new file mode 100644 index 000000000..13404ba81 --- /dev/null +++ b/onprc_ehr/resources/queries/study/BloodCalcBCS.sql @@ -0,0 +1,19 @@ +SELECT c.id, +c.species, +c.gender, +c.DaysAge, +c.Weight, +c.MostRecentWeightDate, +c.date as BCSDate, +c.bcs as BCSScore, +c.CalcMethod, +c.bpk, +c.interval, +c.Percentage, +c.CalcMethodReason, +((c.Weight * (113.753+(0.752 * c.Weight ) - (18.919 * c.bcs)))) as BcsTbv, +(c.bpk*c.Weight) as StandardTBV + + +FROM bloodCalcCriteria c +WHere c.CalcMethod = 'BCS' \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/CageMateInfant.sql b/onprc_ehr/resources/queries/study/CageMateInfant.sql index da283f4a7..bf0dbe6c9 100644 --- a/onprc_ehr/resources/queries/study/CageMateInfant.sql +++ b/onprc_ehr/resources/queries/study/CageMateInfant.sql @@ -15,17 +15,24 @@ */ + select a.id, -a.room, -e.offspringUnder1Yr as InfantCageMate, +group_concat(e.Id ) as InfantCageMate, a.QCState - from study.housingRoommates a, study.demographicsInfantUnderOne e -where a.RoommateId.Id = e.offspringUnder1Yr -And a.Id.DataSet.demographics.calculated_status.code = 'Alive' -And e.Id.DataSet.demographics.calculated_status.code = 'Alive' -and a.roommateEnd is null -and a.qcstate = 18 -and a.room.housingtype.value = 'Cage Location' \ No newline at end of file + + from study.housing a, study.demographics e +where a.Id <> e.Id +And e.calculated_status.code = 'Alive' +and a.Enddate is null +and a.qcstate = 18 and e.qcstate = 18 +and a.housingType.value = 'Cage Location' +and (a.room.room = e.Id.curLocation.room and a.cage = e.Id.curLocation.cage) +and e.Id.age.ageInyears < 1 + + +Group by a.id, a.QCState + + diff --git a/onprc_ehr/resources/queries/study/Clinical Encounters/.qview.xml b/onprc_ehr/resources/queries/study/Clinical Encounters/.qview.xml new file mode 100644 index 000000000..f1da9f3a4 --- /dev/null +++ b/onprc_ehr/resources/queries/study/Clinical Encounters/.qview.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks.js b/onprc_ehr/resources/queries/study/Clinical Remarks.js index 58a1f6d74..a61f5d162 100644 --- a/onprc_ehr/resources/queries/study/Clinical Remarks.js +++ b/onprc_ehr/resources/queries/study/Clinical Remarks.js @@ -26,30 +26,35 @@ function onUpsert(helper, scriptErrors, row, oldRow){ //for compatibility with old system - var currentVet = []; - LABKEY.Query.selectRows({ - schemaName: 'study', - queryName: 'demographicsAssignedVet', - scope: this, - filterArray: [ - LABKEY.Filter.create('id', row.Id, LABKEY.Filter.Types.EQUAL) - ], - success: function(data){ - if(data.rows && data.rows.length){ - /* var rowData; */ - currentVet = data.rows[0].assignedVet; - // for (var i=0;i - +
Clinical Remarks Open + + + diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks/.qview.xml b/onprc_ehr/resources/queries/study/Clinical Remarks/.qview.xml index 5e6eb94af..9f5ac339e 100644 --- a/onprc_ehr/resources/queries/study/Clinical Remarks/.qview.xml +++ b/onprc_ehr/resources/queries/study/Clinical Remarks/.qview.xml @@ -6,6 +6,7 @@ + diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks/CEG_Plan.qview.xml b/onprc_ehr/resources/queries/study/Clinical Remarks/CEG_Plan.qview.xml new file mode 100644 index 000000000..0bc73f1c6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/Clinical Remarks/CEG_Plan.qview.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/Genetic Ancestry.js b/onprc_ehr/resources/queries/study/Genetic Ancestry.js new file mode 100644 index 000000000..71df2a651 --- /dev/null +++ b/onprc_ehr/resources/queries/study/Genetic Ancestry.js @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +require("ehr/triggers").initScript(this); + +var triggerHelper = new org.labkey.onprc_ehr.query.ONPRC_EHRTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); + +function onInit(event, helper){ + helper.setScriptOptions({ + lookupValidationFields: ['result'] + }); +} + +EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.COMPLETE, 'study', 'Genetic Ancestry', function(event, errors, helper) { + if (!helper.isETL() && helper.getPublicParticipantsModified().length) { + triggerHelper.updateGeographicStatus(helper.getPublicParticipantsModified()); + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/Genetic Ancestry.query.xml b/onprc_ehr/resources/queries/study/Genetic Ancestry.query.xml new file mode 100644 index 000000000..3d2346aab --- /dev/null +++ b/onprc_ehr/resources/queries/study/Genetic Ancestry.query.xml @@ -0,0 +1,42 @@ + + + +
+ + + + + + + + + + + Date Added + + + Date Disabled + + + + + + + + + Result + false + + ehr_lookups + geographic_origins + meaning + + + + true + + +
+
+
+ diff --git a/onprc_ehr/resources/queries/study/InfantsBorntoAssigned.sql b/onprc_ehr/resources/queries/study/InfantsBorntoAssigned.sql new file mode 100644 index 000000000..bf63f45c9 --- /dev/null +++ b/onprc_ehr/resources/queries/study/InfantsBorntoAssigned.sql @@ -0,0 +1,37 @@ +Select +a.Id, +a.date, +a.dam, +a.sire, +(select group_concat( b.project.name) from study.assignment b +where b.qcstate = 18 and b.isActive ='true' And b.participantid = a.dam) ProjectName, + +a.QCState +FROM study.birth a +Where a.dam in (select b.Id from study.assignment b +where b.project.name not in ('0492-02','0492-03','1063') +and b.qcstate = 18 and b.isActive ='true') + +And a.Id.DataSet.demographics.calculated_status.code = 'Alive' +and a.qcstate = 18 +and not(a.species in ('rabbit', 'guinea pig')) + +UNION + +Select +a.Id, +a.date, +a.dam, +a.sire, +(select group_concat( b.project.name) from study.assignment b +where b.qcstate = 18 and b.isActive ='true' And b.participantid = a.dam) ProjectName, + +a.QCState +FROM study.birth a +Where a.dam in (select b.Id from study.assignment b +where b.project.name not in ('0492-02','0492-03','1063') +and b.qcstate = 18 and b.isActive ='true') +And a.Id.DataSet.demographics.calculated_status.code = 'Dead' +and a.qcstate = 18 +and not(a.species in ('rabbit', 'guinea pig')) + diff --git a/onprc_ehr/resources/queries/study/NecropsyToMiscCharges.query.xml b/onprc_ehr/resources/queries/study/NecropsyToMiscCharges.query.xml new file mode 100644 index 000000000..64d133301 --- /dev/null +++ b/onprc_ehr/resources/queries/study/NecropsyToMiscCharges.query.xml @@ -0,0 +1,57 @@ + + + + + Necropsy To Misc Charges Report + + + + Id + + + Charge Date + + + Necropsy Procedure Name + + + Necropsy Case No + + + Necropsy Date + + + Necropsy Center Project + + + Necropsy Investigator + + + Necropsy TaskID + + + + Misc Center Project + + + Charge Name + + + Quantity + + + Unit Cost + + + Charge Category + + + + Misc TaskID + + +
+
+
+
+ diff --git a/onprc_ehr/resources/queries/study/NecropsyToMiscCharges.sql b/onprc_ehr/resources/queries/study/NecropsyToMiscCharges.sql new file mode 100644 index 000000000..8a41e254c --- /dev/null +++ b/onprc_ehr/resources/queries/study/NecropsyToMiscCharges.sql @@ -0,0 +1,32 @@ +SELECT +b.Id as "NecropsyID", +b.date as "NecropsyDate", +b.procedureid as "Necropsyprocedure", +b.caseno, +b.project as "NecropsyProject", +b.project.investigatorId.lastname as "NecropsyInvestigator", +b.taskid as "NecropsyTaskID", +b.QCstate as "NecropsyStatus", + r1.Id as "MiscID", +r1.date as "MiscDate", +r1.project as "MiscProject", +r1.chargeId, +r1.quantity, +r1.unitCost, +r1.chargecategory, +r1.QCstate as "MiscStatus", +r1.taskid as "MiscTaskID" + + +FROM study.encounters b + + +Left join ( + Select a.Id, a.date, a.project, a.chargeId, a.quantity, a.unitCost, a.chargecategory, a.QCState, a.taskid + from onprc_billing.miscCharges a + Where a.chargeid.rowid in (4484,4485,4486,4487,4488,4489,5283, 4516,5296,5297,5298) + group by a.Id, a.date, a.project, a.chargeId, a.quantity, a.unitCost, a.chargecategory, a.QCState, a.taskid + +) r1 on (r1.id = b.id ) +Where b.type = 'Necropsy' + diff --git a/onprc_ehr/resources/queries/study/NecropsyToMiscCharges/.qview.xml b/onprc_ehr/resources/queries/study/NecropsyToMiscCharges/.qview.xml new file mode 100644 index 000000000..6895486f9 --- /dev/null +++ b/onprc_ehr/resources/queries/study/NecropsyToMiscCharges/.qview.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/Pairings.query.xml b/onprc_ehr/resources/queries/study/Pairings.query.xml index 4ab8684e0..3f4f573bf 100644 --- a/onprc_ehr/resources/queries/study/Pairings.query.xml +++ b/onprc_ehr/resources/queries/study/Pairings.query.xml @@ -9,45 +9,37 @@ - - - - Pair Id This is used to identify the lowest cage number of the pair. It is used to determine which animals in the group are considered part of the pair. - - Pair ID - true - This field is used to differentiate pairs. By convention is should usually be the lowest cage number in the group; however, it does not need to match this - Room Cage + + Start Date + - Event Type + Start Type - ehr_lookups - pairingEventType + onprc_ehr + PairingStartType value + + - - true - Housing Type - - ehr_lookups - pairingHousingType - value - + + Start Remark + 50 + - Pair Goal + Divider Goal ehr_lookups pairingGoal @@ -55,13 +47,36 @@ - Pair Outcome + Divider Outcome ehr_lookups pairingOutcome value + + false + End Date + + + + End Type + + onprc_ehr + PairingEndType + value + + + + + Separation Reason + + ehr_lookups + pairingSeparationReason + value + + + Observation @@ -70,16 +85,27 @@ value - - Separation Reason + + + End Remark + 200 + + + + + + true + Housing Type ehr_lookups - pairingSeparationReason + pairingHousingType value - - Remark + + Pair ID + true + This field is used to differentiate pairs. By convention is should usually be the lowest cage number in the group; however, it does not need to match this Performed By diff --git a/onprc_ehr/resources/queries/study/ParentageCompleted.query.xml b/onprc_ehr/resources/queries/study/ParentageCompleted.query.xml new file mode 100644 index 000000000..dfd40838f --- /dev/null +++ b/onprc_ehr/resources/queries/study/ParentageCompleted.query.xml @@ -0,0 +1,52 @@ + + + + + Complete Parentage + + + + Area + + + Room + + + Cage + + + + Projects and Groups + + + + Gender + + + Status + + + Birth Date + + + Current Weight + + + Weight Date + + + + Observed Dam + + + Genetic Dam + + + Foster Dam + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/ParentageCompleted.sql b/onprc_ehr/resources/queries/study/ParentageCompleted.sql new file mode 100644 index 000000000..044c4946f --- /dev/null +++ b/onprc_ehr/resources/queries/study/ParentageCompleted.sql @@ -0,0 +1,37 @@ + + + +SELECT + + d.Id.curLocation.area as Area, + d.Id.curLocation.room as Room, + d.Id.curLocation.cage as Cage, + d.Id, + (select e.groupId.name from study.animal_group_members e where e.Id = d.id and e.qcstate = 18 And e.enddate is null) as Project, ------- assigned groups, + d.gender.meaning as gender, + d.calculated_status.code as livestatus, + d.birth as birthdate, + d.Id.MostRecentWeight.MostRecentWeight as currentweight , + d.Id.MostRecentWeight.MostRecentWeightDate as weightdate, + + coalesce(b.dam, '') as observeddam, + coalesce(p2.parent, '') as geneticdam, + coalesce(p3.parent, '') as fosterdam + + +FROM study.demographics d + +LEFT JOIN ( + select p2.id, min(p2.method) as method, max(p2.parent) as parent + FROM study.parentage p2 + WHERE (p2.method = 'Genetic' OR p2.method = 'Provisional Genetic') AND p2.relationship = 'Dam' --AND p2.enddate IS NULL + GROUP BY p2.Id +) p2 ON (d.Id = p2.id) +LEFT JOIN ( + select p3.id, min(p3.method) as method, max(p3.parent) as parent + FROM study.parentage p3 + WHERE p3.relationship = 'Foster Dam' + GROUP BY p3.Id +) p3 ON (d.Id = p3.id) +LEFT JOIN study.birth b ON (b.id = d.id ) +Where d.calculated_status.code = 'Alive' And d.qcstate = 18 \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/ParentageCompleted/.qview.xml b/onprc_ehr/resources/queries/study/ParentageCompleted/.qview.xml new file mode 100644 index 000000000..a4fac810f --- /dev/null +++ b/onprc_ehr/resources/queries/study/ParentageCompleted/.qview.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/SLAOccupiedLocations.sql b/onprc_ehr/resources/queries/study/SLAOccupiedLocations.sql new file mode 100644 index 000000000..285348715 --- /dev/null +++ b/onprc_ehr/resources/queries/study/SLAOccupiedLocations.sql @@ -0,0 +1,13 @@ +SELECT +r.room, +r.building, +--c.room, +c.Species, +c.Date, +c.Animal_Count, +c.Cage_Count, +c.recentdate +FROM "/ONPRC/EHR".ehr_lookups.rooms r +Left join "/ONPRC/sla".sla.SLAMostRecentCensus c on r.room = c.room +Where r.housingType.value = 'Rodent Location' +and r.datedisabled is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/Weight/Weight Details.qview.xml b/onprc_ehr/resources/queries/study/Weight/Weight Details.qview.xml new file mode 100644 index 000000000..ab41e5154 --- /dev/null +++ b/onprc_ehr/resources/queries/study/Weight/Weight Details.qview.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/alopeciaData.sql b/onprc_ehr/resources/queries/study/alopeciaData.sql index 8817c8ef6..e6f1f0269 100644 --- a/onprc_ehr/resources/queries/study/alopeciaData.sql +++ b/onprc_ehr/resources/queries/study/alopeciaData.sql @@ -14,38 +14,34 @@ * limitations under the License. */ SELECT -pvt.*, -grp.performedBy -FROM -(SELECT - o.Id, - max(o.date) as date, - o.taskId, - o.category, - (SELECT group_concat(distinct d.code.meaning) as code FROM study.drug d WHERE d.Id = o.Id AND d.taskId = o.taskId AND d.code IN ('E-70590', 'E-YY992')) as sedation, - group_concat(DISTINCT o.observation, ',') as observation, - (SELECT group_concat(distinct room) as rooms - FROM study.housing h - WHERE h.Id = o.Id AND h.date <= max(o.date) AND h.enddateTimeCoalesced >= timestampadd('SQL_TSI_DAY', -30, max(o.date))) as rooms, - (SELECT group_concat(distinct room.area) as areas FROM study.housing h - WHERE h.Id = o.Id AND h.date <= max(o.date) AND h.enddateTimeCoalesced >= timestampadd('SQL_TSI_DAY', -30, max(o.date))) as areas +o.Id, +o.taskId, +o.Id.Demographics.species as Specie, +o.Id.demographics.gender as Gender, +max(o.date) as date, +o.dateMonthNumber as MonthNumber, +o.ageAtTime.AgeAtTimeYearsRounded as AgeTimeYears, +o.category, +(SELECT group_concat(distinct d.code.meaning) as code FROM study.drug d WHERE d.Id = o.Id AND d.taskId = o.taskId AND d.code IN ('E-70590', 'E-YY992')) as sedation, +group_concat(DISTINCT o.observation, ',') as observation, +group_concat(DISTINCT o.remark, ',') as remark, +max(o.performedby) as performedBy, +max(o.housingAtTime.RoomAtTime) as RoomAtTime, +max(o.groupsAtTime.groupsAtTime) as GroupAtTime, +(SELECT group_concat(distinct room) as rooms FROM study.housing h +WHERE h.Id = o.Id + AND h.date <= max(o.date) + AND h.enddateTimeCoalesced >= timestampadd('SQL_TSI_DAY', -30, max(o.date)) +) as rooms, +(SELECT group_concat(distinct room.area) as areas FROM study.housing h +WHERE h.Id = o.Id + AND h.date <= max(o.date) + AND h.enddateTimeCoalesced >= timestampadd('SQL_TSI_DAY', -30, max(o.date)) +) as areas FROM study.clinical_observations o WHERE o.category IN ('Alopecia Score', 'Alopecia Type', 'Alopecia Regrowth') --note: this is a fairly arbitrary cutoff, used because we only started tracking these measures after this date and date > '2014-05-01' -GROUP BY o.Id, o.taskId, o.category -PIVOT observation BY category IN ('Alopecia Score', 'Alopecia Type', 'Alopecia Regrowth')) pvt - -LEFT OUTER JOIN - -(SELECT - b.Id, - b.taskId, - group_concat(DISTINCT b.performedby, ',') as performedBy - FROM study.clinical_observations b -WHERE b.category IN ('Alopecia Score', 'Alopecia Type', 'Alopecia Regrowth') -and date > '2014-05-01' -GROUP BY b.Id, b.taskId) grp - -ON pvt.Id = grp.Id AND pvt.taskId = grp.taskId \ No newline at end of file +GROUP BY o.Id, o.taskId, o.Id.Demographics.species, o.Id.demographics.gender,o.dateMonthNumber,o.ageAtTime.AgeAtTimeYearsRounded , o.category +PIVOT observation,remark BY category IN ('Alopecia Score', 'Alopecia Type', 'Alopecia Regrowth') diff --git a/onprc_ehr/resources/queries/study/alopeciaData/.qview.xml b/onprc_ehr/resources/queries/study/alopeciaData/.qview.xml index 336b92006..8bb4cadc1 100644 --- a/onprc_ehr/resources/queries/study/alopeciaData/.qview.xml +++ b/onprc_ehr/resources/queries/study/alopeciaData/.qview.xml @@ -1,15 +1,22 @@ + + - - - + + + + + + + + diff --git a/onprc_ehr/resources/queries/study/bloodCalcCriteria.sql b/onprc_ehr/resources/queries/study/bloodCalcCriteria.sql new file mode 100644 index 000000000..7dc60b4b6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/bloodCalcCriteria.sql @@ -0,0 +1,29 @@ +SELECT d.id, +d.species, +d.gender, +d.DaysAge, +d.MostRecentWeight as weight, +d.MostRecentWeightDate, +d.date, +d.score as bcs, +d.blood_per_kg as bpk, +d.blood_draw_interval as interval, +d.max_draw_pct as Percentage, +Case + When d.species <> 'Rhesus Macaque' then 'Fixed Rate by Speices' + WHen d.score is Null then 'Fixed Rate no BCS' + when TIMESTAMPDIFF('SQL_TSI_DAY',d.date,Now()) > 548 Then 'Fixed Rate BCS out of Date' + when d.DaysAge < 730 then 'Fixed Rate NHP Too Young' + + else 'BCS' + End as CalcMethodReason, +Case + When d.species <> 'Rhesus Macaque' then 'Fr' + WHen d.score is Null then 'fr' + when TIMESTAMPDIFF('SQL_TSI_DAY',d.date,Now()) > 548 Then 'fr' + when d.DaysAge < 730 then 'Fr' + + else 'BCS' + End as CalcMethod + +FROM blooddrawDemographics d \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/bloodCalcFixedRate.sql b/onprc_ehr/resources/queries/study/bloodCalcFixedRate.sql new file mode 100644 index 000000000..1e36afc2b --- /dev/null +++ b/onprc_ehr/resources/queries/study/bloodCalcFixedRate.sql @@ -0,0 +1,17 @@ +SELECT c.id, +c.species, +c.gender, +c.DaysAge, +c.Weight, +c.MostRecentWeightDate, +c.date as BCSDate, +c.bcs as BCSScore, +c.CalcMethod, +c.bpk, +c.interval, +c.Percentage, +c.CalcMethodReason, +(c.bpk*c.Weight) as TOtalBloodVolume + +FROM bloodCalcCriteria c +WHere c.CalcMethod = 'FR' \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/bloodCalcPastandFuture.sql b/onprc_ehr/resources/queries/study/bloodCalcPastandFuture.sql new file mode 100644 index 000000000..e26199119 --- /dev/null +++ b/onprc_ehr/resources/queries/study/bloodCalcPastandFuture.sql @@ -0,0 +1,36 @@ +/* +* 2017/9/20 Updated statement to handle an issue where records where the qc state was set to deleted, caancelled or pending approval were being +* marked as counts against volume. The method used here was to determine the current qcstate and exclude these values + */ + +Select bd.id, +0 as FutureDraws, +bd.qcState, +COALESCE + +(Sum(bd.quantity),0) as PreviousDraws + + +from blood bd join study.bloodCalcTotalAllowableBlood d on bd.id = d.id +where +bd.dateOnly >= cast(TIMESTAMPADD('SQL_TSI_DAY', -1 * d.species.blood_draw_interval, now()) as date) +AND bd.dateOnly <= cast(curdate() as date) +--and (bd.countsAgainstVolume = true) +and bd.QCState not in (19,22,23,27) +group by bd.id,bd.qcstate + +Union + +Select bd.id, + +COALESCE + +(Sum(bd.quantity),0) as FutureDraws, +bd.qcState, +0 as PreviousDraws +from blood bd join study.bloodCalcTotalAllowableBlood d on bd.id = d.id +where bd.dateOnly <= cast(TIMESTAMPADD('SQL_TSI_DAY', d.species.blood_draw_interval, curdate()) as date) + AND bd.dateOnly >= cast(curdate() as date) +--and (bd.countsAgainstVolume = true) +and bd.QCState not in (19,22,23,27) +group by bd.id,bd.qcstate diff --git a/onprc_ehr/resources/queries/study/bloodCalcTotalAllowableBlood.sql b/onprc_ehr/resources/queries/study/bloodCalcTotalAllowableBlood.sql new file mode 100644 index 000000000..cacd9355f --- /dev/null +++ b/onprc_ehr/resources/queries/study/bloodCalcTotalAllowableBlood.sql @@ -0,0 +1,24 @@ +SELECT c.id, +c.species, +c.gender, +c.DaysAge, +c.weight, +c.MostRecentWeightDate, +c.date, +c.bcs, +c.bpk, +c.interval, +c.Percentage, +c.CalcMethodReason, +c.CalcMethod, +(Select fr.totalBloodVolume from study,bloodcalcFixedRate fr where c.id = fr.id) as TotalBloodVolumeFR, +(Select b.bcstbv from study.Bloodcalcbcs b where c.id = b.id) as TotalBloodVolumeBCS, + +CAST( +Case + When c.CalcMethod = 'fr' then + (Select (fr.totalBloodVolume * c.percentage) as frtba from study,bloodcalcFixedRate fr where c.id = fr.id) + When c.calcMethod = 'BCS' then + (Select (b.bcstbv * c.percentage) as bcstba from study.Bloodcalcbcs b where c.id = b.id) + End AS DOUBLE) as ABV +FROM bloodCalcCriteria c \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/bloodCalcTotalAvailableBlood.sql b/onprc_ehr/resources/queries/study/bloodCalcTotalAvailableBlood.sql new file mode 100644 index 000000000..e58ebf0c0 --- /dev/null +++ b/onprc_ehr/resources/queries/study/bloodCalcTotalAvailableBlood.sql @@ -0,0 +1,22 @@ +SELECT a.id, +a.species, +a.gender, +a.DaysAge, +a.weight, +a.MostRecentWeightDate, +a.date, +a.bcs, +a.bpk, +a.interval, +a.Percentage, +a.CalcMethodReason, +a.CalcMethod, +a.ABV as TotalAllowableBlood, +fp.PreviousDraws, +fp.futureDraws, +Case + When fp.PReviousDraws > fp.futureDraws then (a.ABV - fp.PReviousDraws) + When fp.FutureDraws > fp.PReviousDraws then (a.abv - fp.futureDraws) + else ABV + End as TotalAvailableBlood +FROM bloodCalcTotalAllowableBlood a left outer join bloodCalcPastandFuture fp on a.id = fp.id \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/blooddrawDemographics.sql b/onprc_ehr/resources/queries/study/blooddrawDemographics.sql new file mode 100644 index 000000000..0c23c2cf6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/blooddrawDemographics.sql @@ -0,0 +1,35 @@ +/**** +2017/1-/15 Issue with Blank G +Tores o resolve the issue of BCS Score being blank, I changed the source from the demographcis Table to a direct read from BCS + + +*** */ + + +select +d.id, +d.species, +d.gender, +Case + when b.date is not null then TIMESTAMPDIFF('SQL_TSI_Day', b.date,Now()) + else (Select TIMESTAMPDIFF('SQL_TSI_Day', a.date,Now()) from study.arrival a where a.id = d.id ) + End as DaysAge, +--d.id.age.ageinDays as DaysAge, +w.MostRecentWeight, +w.MostRecentWeightDate, + +--d.Id.mostRecentBCS.date, +--d.Id.mostRecentBCS.score, +mbcs.date, +mbcs.score, +d.species.max_draw_pct , +d.species.blood_draw_interval, + d.species.blood_per_kg + + +from study.demographics d + left outer join study.birth b on d.id = b.id + left outer join study.demographicsMostRecentWeight w on d.id = w.id + left outer join demographicsMostRecentBCS mbcs on mbcs.id = d.id +where d.calculated_status = 'Alive' +and d.ID not like '[a-z]%' \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/chemPivot.query.xml b/onprc_ehr/resources/queries/study/chemPivot.query.xml index ff96cd5d8..cbe469f70 100644 --- a/onprc_ehr/resources/queries/study/chemPivot.query.xml +++ b/onprc_ehr/resources/queries/study/chemPivot.query.xml @@ -18,7 +18,8 @@ Id
- + + Testing Performed By diff --git a/onprc_ehr/resources/queries/study/chemPivot.sql b/onprc_ehr/resources/queries/study/chemPivot.sql index bb7a12e6e..809c35117 100644 --- a/onprc_ehr/resources/queries/study/chemPivot.sql +++ b/onprc_ehr/resources/queries/study/chemPivot.sql @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 LabKey Corporation + * Copyright (c) 2013-2017 LabKey Corporation * * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 */ @@ -13,7 +13,7 @@ FROM b.Id, b.date, b.method, - b.chargetype, ---Added 9-14-2015 Blasa + b.createdby, ---Added 5-10-2017 R.Blasa b.testId, group_concat(b.result) as results FROM ( @@ -26,7 +26,8 @@ FROM --NOTE: removed to allow legacy runs to group into 1 row. since we already group on Id/Date/Test, this should be ok --coalesce(b.taskId, b.runId) as groupingId, b.runid.method as method, - b.runid.chargetype as chargetype, ---Added 9-14-2015 Blasa + b.createdby.DisplayName as createdby, ---Added 5-10-2017 R.Blasa + b.remark, b.runId.remark as runRemark, b.resultoorindicator, @@ -40,7 +41,7 @@ FROM ) b --Updated 6-3-2015 Blasa - GROUP BY b.runid,b.id, b.date, b.testId, b.method, b.chargetype + GROUP BY b.runid,b.id, b.date, b.testId, b.method, b.createdby PIVOT results BY testId IN (select testid from ehr_lookups.chemistry_tests t WHERE t.includeInPanel = true order by sort_order)) pivot_ LEFT OUTER JOIN @@ -48,7 +49,7 @@ LEFT OUTER JOIN (SELECT group_concat(distinct d.remark, chr(10)) as remark, group_concat(distinct d.runRemark, chr(10)) as runRemark, - d.runid,d.id, d.date, d.method, d.chargetype + d.runid,d.id, d.date, d.method FROM ( @@ -59,7 +60,6 @@ LEFT OUTER JOIN --NOTE: removed to allow legacy runs to group into 1 row. since we already group on Id/Date/Test, this should be ok --coalesce(b.taskId, b.runId) as groupingId, d.runid.method as method, - d.runid.chargetype as chargetype, ---Added 9-14-2015 Blasa d.remark, d.runId.remark as runRemark, d.resultoorindicator, @@ -73,7 +73,7 @@ LEFT OUTER JOIN ) d --Updated 6-3-2015 Blasa - GROUP BY d.runid,d.id, d.date, d.method, d.chargetype) grp + GROUP BY d.runid,d.id, d.date, d.method) grp -ON pivot_.runId = grp.runId AND pivot_.id = grp.id AND pivot_.date = grp.date AND pivot_.method = grp.method AND pivot_.chargetype = grp.chargetype +ON pivot_.runId = grp.runId AND pivot_.id = grp.id AND pivot_.date = grp.date AND pivot_.method = grp.method diff --git a/onprc_ehr/resources/queries/study/chemistryRefRange.sql b/onprc_ehr/resources/queries/study/chemistryRefRange.sql index 2a161f356..f787cb8b5 100644 --- a/onprc_ehr/resources/queries/study/chemistryRefRange.sql +++ b/onprc_ehr/resources/queries/study/chemistryRefRange.sql @@ -33,7 +33,8 @@ END as status, c.remark, c.taskid, c.runId, -c.qcstate +c.qcstate, + r.type FROM ( SELECT @@ -53,6 +54,7 @@ FROM ( c.date, c.runId, c.remark, + c.type, ROUND(CONVERT(age_in_months(c.id.dataset.demographics.birth, c.date), DOUBLE) / 12.0, 1) as ageAtTime FROM "Chemistry Results" c WHERE c.qcstate.publicdata = true @@ -66,9 +68,9 @@ FROM ( LEFT JOIN ehr_lookups.lab_test_range r ON ( c.testId = r.test AND - c.species = r.species AND + (c.species = r.species or (c.species is not null and r.species is null)) AND --(ac.ageClass = r.age_class OR (ac.ageClass IS NULL AND r.age_class IS NULL)) AND - c.gender = r.gender and - r.type = 'Chemistry' + (c.gender = r.gender or (c.gender is not null and r.gender is null)) and + coalesce(c.type,'Biochemistry') = r.type ) diff --git a/onprc_ehr/resources/queries/study/clinicalCases.sql b/onprc_ehr/resources/queries/study/clinicalCases.sql index 6f1a97984..487cffa1d 100644 --- a/onprc_ehr/resources/queries/study/clinicalCases.sql +++ b/onprc_ehr/resources/queries/study/clinicalCases.sql @@ -25,7 +25,8 @@ SELECT c.remark, c.mostRecentP2, c.isActive, - c.assignedvet + c.assignedvet, + c.mostRecentCeg_Plan FROM study.cases c WHERE c.isActive = true AND c.category = 'Clinical' @@ -33,9 +34,8 @@ WHERE c.isActive = true AND c.category = 'Clinical' UNION ALL SELECT - d.Id, - d.date, - + h.Id, + h.date, null as enddate, null as reviewdate, null as category, @@ -45,7 +45,9 @@ SELECT null as remark, null as mostrecentP2, null as isActive, - null as assignedVet + null as assignedVet, + null as mostRecentCeg_Plan -FROM study.demographicsCurrentLocation d -WHERE d.area = 'Hospital' AND (d.Id.activecases.categories NOT LIKE '%Clinical%' OR d.Id.activecases.categories IS NULL) \ No newline at end of file +FROM study.housing h +WHERE h.room.area = 'Hospital' and h.enddate is null +and h.id not in (Select c1.id from study.cases c1 where c1.id = h.id and c1.IsActive = true) diff --git a/onprc_ehr/resources/queries/study/currentBloodAvailable.sql b/onprc_ehr/resources/queries/study/currentBloodAvailable.sql index f090a8d81..b2f325ba8 100644 --- a/onprc_ehr/resources/queries/study/currentBloodAvailable.sql +++ b/onprc_ehr/resources/queries/study/currentBloodAvailable.sql @@ -29,6 +29,7 @@ SELECT t.blood_per_kg, t.mostRecentWeight, t.mostRecentWeightDate, + t.AllowableBlood FromOriginalQUery, cast(t.allowableBlood as double) as maxAllowableBlood, cast(t.bloodPrevious as double) as bloodPrevious, cast((t.allowableBlood - t.bloodPrevious) as double) as allowablePrevious, @@ -52,16 +53,20 @@ SELECT bd.id, bd.dateOnly as date, bd.quantity, - d.species, - d.id.mostRecentWeight.MostRecentWeight, - d.id.mostRecentWeight.MostRecentWeightDate, + b.species, + b.weight as MostRecentWeight, + b.MostRecentWeightDate, + /* d.id.mostRecentWeight.MostRecentWeight, + d.id.mostRecentWeight.MostRecentWeightDate,*/ d.species.blood_per_kg, d.species.max_draw_pct, bd.blood_draw_interval, b.allowableBlood, bd.minDate, bd.maxDate, - COALESCE( + b.PreviousDraws as BloodPrevious, + b.FutureDraws as BloodFuture, + /* COALESCE( (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr FROM study."Blood Draws" draws WHERE draws.id = bd.id @@ -79,7 +84,7 @@ SELECT AND draws.dateOnly >= bd.dateOnly --NOTE: this has been changed to include penidng/non-approved draws AND draws.countsAgainstVolume = true - ), 0) AS BloodFuture + ), 0) AS BloodFuture*/ FROM study.bloodDrawChanges bd JOIN study.DemographicsBloodSummary b on (b.id = bd.id) diff --git a/onprc_ehr/resources/queries/study/currentBloodDraws.query.xml b/onprc_ehr/resources/queries/study/currentBloodDraws.query.xml index b061db414..d5f4d3d67 100644 --- a/onprc_ehr/resources/queries/study/currentBloodDraws.query.xml +++ b/onprc_ehr/resources/queries/study/currentBloodDraws.query.xml @@ -1,38 +1,60 @@ + - - Current Blood Draws +
+ Available Blood + - - 0.## + + true + false - - 0.## - Maximum allowable blood + + Gender - - 0.## - Blood drawn over interval, looking backwards + + Speices - - 0.## - Max allowable blood, accounting for previous draws only + + Year of Birth - - 0.## - Blood drawn over interval, looking forwards + + + Most Recent Weight (kg) + + + Most Recent Weight Date + + + Most Recent BCS + + + Days Since BCS Reported + + + Most Recent BCS Date + + + Calc Method Used - + + + Previous Draws (mL) 0.## - Max allowable blood, accounting for future draws only + 0 - + + + + Total Available blood(mL) 0.## - Max allowable blood on this date + + availBlood
-
\ No newline at end of file + + diff --git a/onprc_ehr/resources/queries/study/currentBloodDraws.sql b/onprc_ehr/resources/queries/study/currentBloodDraws.sql index ab11c1e06..ebf5fa62e 100644 --- a/onprc_ehr/resources/queries/study/currentBloodDraws.sql +++ b/onprc_ehr/resources/queries/study/currentBloodDraws.sql @@ -17,71 +17,18 @@ */ SELECT - t.id, - t.date, - cast(t.quantity as double) as quantity, - t.species, - t.max_draw_pct, - t.blood_draw_interval, - t.blood_per_kg, - t.mostRecentWeight, - t.mostRecentWeightDate, - cast(t.allowableBlood as double) as maxAllowableBlood, - cast(t.bloodPrevious as double) as bloodPrevious, - cast((t.allowableBlood - t.bloodPrevious) as double) as allowablePrevious, + bs.id + ,bs.gender + ,bs.species + ,bs.yoa as YearofBirth + ,bs.mostrecentweightdate + ,bs.weight as MostRecentWeight + ,bs.calcmethod as CalculationMethod + ,bs.BCS as MostRecentBCS + ,bs.BCSage + ,bs.previousdraws + ,bs.ABV as TotalAvailableBlood - cast(t.bloodFuture as double) as bloodFuture, - cast((t.allowableBlood - t.bloodFuture) as double) as allowableFuture, - --if the draw is historic, always consider previous draws only. - --otherwise, look both forward and backwards, then take the interval with the highest volume - cast(case - WHEN t.date < curdate() THEN (t.allowableBlood - t.bloodPrevious) - WHEN t.bloodPrevious < t.bloodFuture THEN (t.allowableBlood - t.bloodFuture) - ELSE (t.allowableBlood - t.bloodPrevious) - end as double) as allowableBlood, - t.minDate, - t.maxDate -FROM ( - -SELECT - bd.id, - bd.dateOnly as date, - bd.quantity, - d.species, - d.id.mostRecentWeight.MostRecentWeight, - d.id.mostRecentWeight.MostRecentWeightDate, - d.species.blood_per_kg, - d.species.max_draw_pct, - bd.blood_draw_interval, - bs.availableblood, - bs.allowableBlood, - -- (d.id.mostRecentWeight.MostRecentWeight * d.species.blood_per_kg * d.species.max_draw_pct) as allowableBlood, - bd.minDate, - bd.maxDate, - COALESCE( - (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr - FROM study."Blood Draws" draws - WHERE draws.id = bd.id - AND draws.dateOnly > bd.minDate - AND draws.dateOnly <= bd.dateOnly - --NOTE: this has been changed to include penidng/non-approved draws - AND draws.countsAgainstVolume = true - ), 0) AS BloodPrevious, - - COALESCE( - (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr - FROM study."Blood Draws" draws - WHERE draws.id = bd.id - AND draws.dateOnly < bd.maxDate - AND draws.dateOnly >= bd.dateOnly - --NOTE: this has been changed to include penidng/non-approved draws - AND draws.countsAgainstVolume = true - ), 0) AS BloodFuture - -FROM study.bloodDrawChanges bd -JOIN study.demographics d ON (d.id = bd.id) -Join demographicsBloodSummary bs on (bs.id = bd.id) - -) t \ No newline at end of file +FROM demographicsBloodSummary bs diff --git a/onprc_ehr/resources/queries/study/demographicsBloodSummary.query.xml b/onprc_ehr/resources/queries/study/demographicsBloodSummary.query.xml index 4057765ac..d5f4d3d67 100644 --- a/onprc_ehr/resources/queries/study/demographicsBloodSummary.query.xml +++ b/onprc_ehr/resources/queries/study/demographicsBloodSummary.query.xml @@ -1,59 +1,60 @@ + - +
Available Blood + true - true + false - - true + + Gender - + + Speices + + + Year of Birth + + + Most Recent Weight (kg) - + + Most Recent Weight Date + + + Most Recent BCS + + + Days Since BCS Reported + + + Most Recent BCS Date + + + Calc Method Used + + + Previous Draws (mL) 0.## - /query/executeQuery.view?schemaName=study& - query.queryName=Blood Draws& - query.Id~eq=${Id}& - query.Date~lte=${Date}& - query.sort=-Date& - - - - Future Draws (mL) - 0.## - /query/executeQuery.view?schemaName=study& - query.queryName=Blood Draws& - query.Id~eq=${Id}& - query.Date~gt=${Date}& - query.sort=-Date& - - - - Max blood, assuming no other draws (mL) - 0.## - true + 0 - - Available Blood (mL) + + + + Total Available blood(mL) 0.## - - - - - - FBEC5D - - + availBlood
+ diff --git a/onprc_ehr/resources/queries/study/demographicsBloodSummary.sql b/onprc_ehr/resources/queries/study/demographicsBloodSummary.sql index 4e841ee75..7b34d8eb4 100644 --- a/onprc_ehr/resources/queries/study/demographicsBloodSummary.sql +++ b/onprc_ehr/resources/queries/study/demographicsBloodSummary.sql @@ -1,171 +1,14 @@ -/* - * Copyright (c) 2013-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - * Research completed by Dr Ted Hobbs ONPRC has updated the process for calculating availaable blood - * The new research uses the Body Condition Score of DXA Scan to determine body fat. - * the rule to be applied relates to Rheses Macaque Animals as follows: - ****If a BCS score is recorded that is within the last 365 days the frolumla to be applied is - ****TBV = (113.753 + (0.752 × BW) – (18.919 × BCS))*BW) - ***Total Available is TBV*.125 - ****Else if either no BCS is available or it is older than 1 year, the current method based on standard Available AVolume with be Applied - ** A second process is availbale relating to DXA Scans but these are only performed by Researach Staff and not entered into PRIME - */ - -SELECT - b.lsid, - b.id, - b.Species, - b.Gender, - -b.MostRecentBCS, -b.BCSDate, -b.weight as mostRecentWeight, - b.wdate as mostRecentWeightDate, - b.blood_draw_interval, - b.bloodPrevious, - b.bloodFuture, - b.species.blood_per_kg, -round(b.bloodVolume,2) as FixedRateCalculation, -round(b.TBV,2) as TotalBloodVolume, ---round((b.TBV*.125),2) as AllowableBlood1, - - Case - When species<> 'Rhesus Macaque' --'Fixed Rate Process' - Then round((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct),2) - When - b.DaysSinceBCS > 365 - Then round((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct),2) - When b.MostRecentBCS is not null - Then round((b.TBV * .125),2) - Else round((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct),2) - end As AllowableBlood, - - Case - When species<> 'Rhesus Macaque' --'Fixed Rate Process' - Then - Case - When (b.bloodPrevious>b.bloodFuture) - Then - round(((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct)-b.bloodPrevious),2) - ELSE - round(((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct)-b.bloodFuture),2) - End - When - b.DaysSinceBCS > 365 - then - Case - When b.bloodPrevious > b.bloodFuture - Then - round(((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct)-b.bloodPrevious),2) - Else - round(((b.species.blood_per_kg * b.id.MostRecentWeight.MostRecentWeight * b.max_draw_pct)-b.bloodFuture),2) - End ---Available Blood is Allowable Blood minus the larger of Previous and Future - When - b.MostRecentBCS is not null THEN - Case - When b.bloodPrevious > b.bloodFuture - Then - round(((b.TBV * .125)-b.bloodPrevious),2) - Else - round(((b.TBV * .125)-b.bloodFuture),2) - End - - --- Else - - - - - end As AvailableBlood, - - Case - When species<> 'Rhesus Macaque' Then 'FR' - When - b.DaysSinceBCS > 365 - Then 'FR' - When - b.MostRecentBCS is not null then - 'BCS' - Else'FR' - end As Method - - -FROM ( - -SELECT - d.lsid, - d.id, - d.species, - d.gender, - --NOTE: this uses date part only - lastWeight.dateOnly as wdate, - (SELECT AVG(w.weight) AS _expr - FROM study.weight w - WHERE w.id = d.id - --NOTE: this uses date part only - AND w.dateOnly = lastWeight.dateOnly - AND w.qcstate.publicdata = true - ) AS weight, - d.species.blood_per_kg, - d.species.max_draw_pct , - d.species.blood_draw_interval, - Cast(d.species.cites_Code as Float) as SpeciesCode, - bcs.score as MostRecentBCS, - bcs.date as BCSDate, - TIMESTAMPDIFF('SQL_TSI_DAY',bcs.date,Now()) as DaysSinceBCS, - --This ca;ciates tje tt - Case - when TIMESTAMPDIFF('SQL_TSI_DAY',bcs.date,Now()) < 365 THEN round(cast (113.753 + ((0.752 * d.id.MostRecentWeight.MostRecentWeight ) - (18.919 * bcs.score))as double),2) - Else (d.species.blood_per_kg * d.id.MostRecentWeight.MostRecentWeight) - END as TotalBloodAvailable, - - - - COALESCE (( - SELECT - SUM(bd.quantity) AS quantity - FROM study.blood bd - WHERE bd.id = d.id - --NOTE: this has been changed in the DB to include penidng/non-approved draws - AND (bd.countsAgainstVolume = true) --NOTE: this does mean non-completed past requests will count against blood - AND bd.dateOnly > cast(TIMESTAMPADD('SQL_TSI_DAY', -1 * d.species.blood_draw_interval, now()) as date) - AND bd.dateOnly <= cast(curdate() as date) - ), 0) AS bloodPrevious, --- ***************New Calculation Base *********************************************** - - -- blood volume (ml/kg) -------113.753+(0.752*Wt)- (18.919*BCS) -(113.753+(0.752 * d.id.MostRecentWeight.MostRecentWeight ) - (18.919 * bcs.score)) as BloodVolume, - ---TBV(mnl) ------weight * Blood Volume -(d.id.MostRecentWeight.MostRecentWeight * (113.753+(0.752 * d.id.MostRecentWeight.MostRecentWeight ) - (18.919 * bcs.score))) as TBV, ---Allowable BV ------TBV*.125 - - ---***********************Determines Previous and Future Blood******************************** - COALESCE (( - SELECT - SUM(bd.quantity) AS quantity - FROM study.blood bd - WHERE bd.id = d.id - --NOTE: this has been changed to include penidng/non-approved draws - AND (bd.countsAgainstVolume = true) - AND bd.dateOnly < cast(TIMESTAMPADD('SQL_TSI_DAY', d.species.blood_draw_interval, curdate()) as date) - AND bd.dateOnly >= cast(curdate() as date) - ), 0) AS bloodFuture - - - - -FROM - study.demographics d - --NOTE: this uses date part only - JOIN (SELECT w.id, MAX(dateOnly) as dateOnly FROM study.weight w WHERE w.qcstate.publicdata = true GROUP BY w.id) lastWeight ON (d.id = lastWeight.id) - LEFT OUTER JOIN study.demographicsCurrentBCS bcs on bcs.id = d.id -WHERE d.calculated_status = 'Alive' - -) b \ No newline at end of file +SELECT datecreated + ,id + ,gender + ,species + ,yoa + ,mostrecentweightdate + ,weight + ,calcmethod + ,BCS + ,BCSage + ,previousdraws + ,ABV + ,dsrowid +FROM onprc_ehr.AvailableBloodVolume \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/demographicsBloodSummary/.qview.xml b/onprc_ehr/resources/queries/study/demographicsBloodSummary/.qview.xml index da6699561..097ecaa31 100644 --- a/onprc_ehr/resources/queries/study/demographicsBloodSummary/.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsBloodSummary/.qview.xml @@ -3,16 +3,18 @@ - - - + + + - - - - - - + + + + + - \ No newline at end of file + + + + diff --git a/onprc_ehr/resources/queries/study/demographicsGeneticAncestry.query.xml b/onprc_ehr/resources/queries/study/demographicsGeneticAncestry.query.xml new file mode 100644 index 000000000..b95a27bbc --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsGeneticAncestry.query.xml @@ -0,0 +1,15 @@ + + + + + Genetic Ancestry + + + true + true + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/demographicsGeneticAncestry.sql b/onprc_ehr/resources/queries/study/demographicsGeneticAncestry.sql new file mode 100644 index 000000000..4b24cac01 --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsGeneticAncestry.sql @@ -0,0 +1,7 @@ +SELECT +d.Id, +group_concat(distinct d.result) as geneticAncestry + +FROM study.geneticAncestry d +WHERE d.isActive = true +GROUP BY d.Id \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/demographicsMostRecentBCS.sql b/onprc_ehr/resources/queries/study/demographicsMostRecentBCS.sql index 432b03dbc..5c55a710d 100644 --- a/onprc_ehr/resources/queries/study/demographicsMostRecentBCS.sql +++ b/onprc_ehr/resources/queries/study/demographicsMostRecentBCS.sql @@ -2,25 +2,39 @@ * Copyright (c) 2014 LabKey Corporation * * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + * updated 9/4/2017 by Kolli to adjust issue of multiple bcs on same date + * results verified in Test and readyfor Production */ +Select DISTINCT +a.id, +CAST(a.date AS DATE) as date, +a.score +From +(Select b.id, b.date, b.score + From study.BCS_Recent_Score b + Where b.score = (Select Min(b1.score) from study.BCS_Recent_Score b1 where b1.id =b.id) +) AS a -select - co.Id, - max(co2.maxDate) as date, - group_concat(DISTINCT co.observation) as score -from study.clinical_observations co -join ( - SELECT - co.Id, - max(co.date) as maxDate - FROM study.clinical_observations co - WHERE co.qcstate.publicdata = true AND co.category = 'BCS' - GROUP BY co.Id -) co2 ON (co.Id = co2.Id AND co.date = co2.maxDate) -WHERE co.qcstate.publicdata = true AND co.category = 'BCS' -GROUP BY co.Id +/* code as of 9/1/2017 +Select +b.id, +b.date, +b.observation as score +from study.clinical_observations b +where b.category = 'bcs' +and b.created > TIMESTAMPADD('SQL_TSI_MONTH', -18, Now()) +and b.date = (Select Max(b2.date) from study.clinical_observations b2 where b2.id =b.id and b2.category = 'bcs' and b2.observation is not null) +and b.observation = (Select Min(b1.observation) from study.clinical_observations b1 where b1.id =b.id and b1.category = 'bcs' and b1.observation is not null) +and b.observation is not null + and b.id not like '[a-z]%'*/ + + + +-- when coiunt more than 1 use smallest value +-- need to determine when 2 bcs scores are entered for the same date, then use min bCS + diff --git a/onprc_ehr/resources/queries/study/demographicsOffspring.sql b/onprc_ehr/resources/queries/study/demographicsOffspring.sql index b68cb6e3f..82ba0fe31 100644 --- a/onprc_ehr/resources/queries/study/demographicsOffspring.sql +++ b/onprc_ehr/resources/queries/study/demographicsOffspring.sql @@ -6,7 +6,7 @@ SELECT d.id, -d.gender, +d.gender.meaning as gender, 'Offspring' as Relationship, d2.id AS Offspring, @@ -17,5 +17,7 @@ d.qcstate FROM study.Demographics d INNER JOIN study.Demographics d2 - ON ((d2.id.parents.sire = d.id OR d2.id.parents.dam = d.id) AND d.id != d2.id) + ON ((d2.id.parents.sire = d.id OR d2.id.parents.dam = d.id OR d2.id.parents.fostermom = d.id) AND d.id != d2.id) + + diff --git a/onprc_ehr/resources/queries/study/demographicsOffspring/.qview.xml b/onprc_ehr/resources/queries/study/demographicsOffspring/.qview.xml index 0fd322a62..a1b484e9e 100644 --- a/onprc_ehr/resources/queries/study/demographicsOffspring/.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsOffspring/.qview.xml @@ -13,6 +13,9 @@ + + + diff --git a/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml new file mode 100644 index 000000000..161f83fec --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml @@ -0,0 +1,59 @@ + + + + + + + true + + + + /query/executeQuery.view?schemaName=study& + query.queryName=demographicsOffspringBSU& + query.Id~eq=${Id} + + + + + study + animal + Id + + + + Gender + + + Birth + + + Birth Type + + + Status + + + + Genetic Dam + + + + Observed Dam + + + Foster Dam + + + + Sire + + + + Sire type + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql new file mode 100644 index 000000000..26a72138b --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +SELECT + +d.id, +d.gender.meaning as gender, +'Offspring' as Relationship, + +d2.id AS Offspring, +d2.birth, +d2.birthType, +d2.offspringgender, +d2.status, +d2.geneticdam, +d2.observeddam, +d2.fosterMom, +d2.sire, +d2.sireType, +d.qcstate + +FROM study.Demographics d + +INNER JOIN study.demographicsParentsBSU d2 + + ON ((d2.sire = d.id OR d2.geneticdam = d.id OR d2.fostermom = d.id OR d2.observeddam = d.id) AND d.id != d2.id) + + + diff --git a/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml b/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml new file mode 100644 index 000000000..cda4e0878 --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/demographicsParents.query.xml b/onprc_ehr/resources/queries/study/demographicsParents.query.xml index a151cf172..e3ef57f38 100644 --- a/onprc_ehr/resources/queries/study/demographicsParents.query.xml +++ b/onprc_ehr/resources/queries/study/demographicsParents.query.xml @@ -8,6 +8,7 @@ true
+ Dam study animal @@ -15,6 +16,23 @@ + Sire + + study + animal + id + + + + Foster Dam + + study + animal + id + + + + Genetic Dam study animal diff --git a/onprc_ehr/resources/queries/study/demographicsParents.sql b/onprc_ehr/resources/queries/study/demographicsParents.sql index f1cebab46..673cc8bb2 100644 --- a/onprc_ehr/resources/queries/study/demographicsParents.sql +++ b/onprc_ehr/resources/queries/study/demographicsParents.sql @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + SELECT d.id, coalesce(p2.parent, b.dam) as dam, @@ -28,24 +29,34 @@ SELECT WHEN b.sire IS NOT NULL THEN 'Observed' ELSE null END as sireType, - CASE - WHEN (coalesce(p2.parent, b.dam) IS NOT NULL AND coalesce(p1.parent, b.sire) IS NOT NULL) THEN 2 - WHEN (coalesce(p2.parent, b.dam) IS NOT NULL OR coalesce(p1.parent, b.sire) IS NOT NULL) THEN 1 - ELSE 0 - END as numParents -FROM study.demographics d + p3.parent as fosterMom, + p3.method as fosterType, + + (CASE WHEN p3.parent IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN coalesce(p2.parent, b.dam) IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN coalesce(p1.parent, b.sire) IS NOT NULL THEN 1 ELSE 0 END) as numParents + +FROM study.demographics d LEFT JOIN ( select p1.id, min(p1.method) as method, max(p1.parent) as parent FROM study.parentage p1 - WHERE (p1.method = 'Genetic' OR p1.method = 'Provisional Genetic') AND p1.relationship = 'Sire' --AND p1.enddate IS NULL + WHERE (p1.method = 'Genetic' OR p1.method = 'Provisional Genetic') AND p1.relationship = 'Sire' AND p1.enddate IS NULL GROUP BY p1.Id ) p1 ON (d.Id = p1.id) + LEFT JOIN ( select p2.id, min(p2.method) as method, max(p2.parent) as parent FROM study.parentage p2 - WHERE (p2.method = 'Genetic' OR p2.method = 'Provisional Genetic') AND p2.relationship = 'Dam' --AND p2.enddate IS NULL + WHERE (p2.method = 'Genetic' OR p2.method = 'Provisional Genetic') AND p2.relationship = 'Dam' AND p2.enddate IS NULL GROUP BY p2.Id ) p2 ON (d.Id = p2.id) + +LEFT JOIN ( + select p3.id, min(p3.method) as method, max(p3.parent) as parent + FROM study.parentage p3 + WHERE p3.relationship = 'Foster Dam' AND p3.enddate IS NULL + GROUP BY p3.Id +) p3 ON (d.Id = p3.id) LEFT JOIN study.birth b ON (b.id = d.id) diff --git a/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml b/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml index ce003e39e..2ab5905b4 100644 --- a/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml @@ -5,6 +5,8 @@ + + diff --git a/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml b/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml new file mode 100644 index 000000000..5790dc400 --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml @@ -0,0 +1,59 @@ + + + + + Parents + + + true + + + true + + + true + + + true + + + Dam + + study + animal + id + + + + Genetic Dam + + study + animal + id + + + + Sire + + study + animal + id + + + + Foster Dam + + study + animal + id + + + + + Number of Parents Known + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql b/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql new file mode 100644 index 000000000..76f64855f --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +SELECT + d.id, + d.birth, + b.type.value as birthType, + b.Id.demographics.gender.meaning as offspringgender, + d.calculated_status as status, + coalesce(p2.parent, '') as geneticdam, + CASE + WHEN p2.parent IS NOT NULL THEN p2.method + ELSE null + END as geneticDamType, + + coalesce(b.dam, '') as observeddam, + CASE + WHEN b.dam IS NOT NULL THEN 'Observed' + ELSE null + END as observedDamType, + + coalesce(p1.parent, b.sire) as sire, + CASE + WHEN p1.parent IS NOT NULL THEN p1.method + WHEN b.sire IS NOT NULL THEN 'Observed' + ELSE null + END as sireType, + + p3.parent as fosterMom, + p3.method as fosterType, + + (CASE WHEN p3.parent IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN coalesce(p2.parent, b.dam) IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN coalesce(p1.parent, b.sire) IS NOT NULL THEN 1 ELSE 0 END) as numParents + +FROM study.demographics d + +LEFT JOIN ( + select p1.id, min(p1.method) as method, max(p1.parent) as parent + FROM study.parentage p1 + WHERE (p1.method = 'Genetic' OR p1.method = 'Provisional Genetic') AND p1.relationship = 'Sire' AND p1.enddate IS NULL + GROUP BY p1.Id +) p1 ON (d.Id = p1.id) + +LEFT JOIN ( + select p2.id, min(p2.method) as method, max(p2.parent) as parent + FROM study.parentage p2 + WHERE (p2.method = 'Genetic' OR p2.method = 'Provisional Genetic') AND p2.relationship = 'Dam' AND p2.enddate IS NULL + GROUP BY p2.Id +) p2 ON (d.Id = p2.id) + +LEFT JOIN ( + select p3.id, min(p3.method) as method, max(p3.parent) as parent + FROM study.parentage p3 + WHERE p3.relationship = 'Foster Dam' AND p3.enddate IS NULL + GROUP BY p3.Id +) p3 ON (d.Id = p3.id) +LEFT JOIN study.birth b ON (b.id = d.id) + diff --git a/onprc_ehr/resources/queries/study/demographicsParentsBSU/.qview.xml b/onprc_ehr/resources/queries/study/demographicsParentsBSU/.qview.xml new file mode 100644 index 000000000..25ca78e42 --- /dev/null +++ b/onprc_ehr/resources/queries/study/demographicsParentsBSU/.qview.xml @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/geneticAncestry/.qview.xml b/onprc_ehr/resources/queries/study/geneticAncestry/.qview.xml new file mode 100644 index 000000000..af9d56dcb --- /dev/null +++ b/onprc_ehr/resources/queries/study/geneticAncestry/.qview.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/geneticAncestry/Active Calls.qview.xml b/onprc_ehr/resources/queries/study/geneticAncestry/Active Calls.qview.xml new file mode 100644 index 000000000..b900c40f2 --- /dev/null +++ b/onprc_ehr/resources/queries/study/geneticAncestry/Active Calls.qview.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/geneticAncestryConflicts.sql b/onprc_ehr/resources/queries/study/geneticAncestryConflicts.sql new file mode 100644 index 000000000..750df0c65 --- /dev/null +++ b/onprc_ehr/resources/queries/study/geneticAncestryConflicts.sql @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +SELECT + p.Id, + group_concat(distinct p.result) as result, + count(p.Id) as totalRecords + +FROM study.geneticAncestry p +WHERE p.qcstate.publicdata = true and p.isActive = true + +GROUP BY p.Id +HAVING COUNT(DISTINCT p.result) > 1 \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/geographicOriginConflicts.sql b/onprc_ehr/resources/queries/study/geographicOriginConflicts.sql new file mode 100644 index 000000000..5985f602a --- /dev/null +++ b/onprc_ehr/resources/queries/study/geographicOriginConflicts.sql @@ -0,0 +1,8 @@ +SELECT +t.Id, +t.geneticAncestry, +d.geographic_origin, + +FROM study.demographicsGeneticAncestry t +JOIN study.demographics d on (t.Id = d.Id) +WHERE t.geneticAncestry != d.geographic_origin OR (t.geneticAncestry IS NOT NULL AND d.geographic_origin IS NULL) diff --git a/onprc_ehr/resources/queries/study/hematologyPivot.query.xml b/onprc_ehr/resources/queries/study/hematologyPivot.query.xml index d61a4a043..4247f31cc 100644 --- a/onprc_ehr/resources/queries/study/hematologyPivot.query.xml +++ b/onprc_ehr/resources/queries/study/hematologyPivot.query.xml @@ -29,7 +29,8 @@ objectid
- + + Testing Performed By diff --git a/onprc_ehr/resources/queries/study/hematologyPivot.sql b/onprc_ehr/resources/queries/study/hematologyPivot.sql index 26f3015cc..7768760a5 100644 --- a/onprc_ehr/resources/queries/study/hematologyPivot.sql +++ b/onprc_ehr/resources/queries/study/hematologyPivot.sql @@ -13,7 +13,7 @@ FROM b.id, b.date, b.method, - b.chargetype, + b.createdby, ---Added 5-10-2017 R.Blasa b.testId, b.runId @hidden, group_concat(b.result) as results @@ -25,7 +25,7 @@ FROM b.date, b.testId, b.runid.method as method, - b.runid.chargetype as chargetype, + b.createdby.DisplayName as createdby, ---Added 5-10-2017 R.Blasa coalesce(b.runId, b.objectid) as runId, CASE WHEN b.result IS NULL THEN b.qualresult @@ -35,7 +35,7 @@ FROM WHERE b.testId.includeInPanel = true and b.qcstate.publicdata = true ) b -GROUP BY b.id, b.date, b.runId, b.testId, b.method, b.chargetype +GROUP BY b.id, b.date, b.runId, b.testId, b.method,b.createdby PIVOT results BY testId IN (select testid from ehr_lookups.hematology_tests t WHERE t.includeInPanel = true)) pvt @@ -47,7 +47,7 @@ LEFT OUTER JOIN group_concat(distinct servicerequested, chr(10)) as servicerequested, b.runId, b.method, - b.chargetype, + b.createdby, ---Added 5-10-2017 R.Blasa, group_concat(distinct b.remark, chr(10)) as remark, group_concat(distinct b.runRemark, chr(10)) as runRemark @@ -57,7 +57,7 @@ FROM ( b.id, b.date, b.runid.method as method, - b.runid.chargetype as chargetype, + b.createdby.DisplayName as createdby, ---Added 5-10-2017 R.Blasa b.runid.servicerequested as servicerequested, coalesce(b.runId, b.objectid) as runId, b.remark, @@ -66,6 +66,6 @@ FROM ( WHERE b.testId.includeInPanel = true and b.qcstate.publicdata = true ) b -GROUP BY b.id, b.date, b.runId, b.method, b.chargetype) grp +GROUP BY b.id, b.date, b.runId, b.method, b.createdby) grp -ON pvt.id = grp.id AND pvt.date = grp.date AND pvt.runID = grp.runId AND pvt.method = grp.method AND pvt.chargetype = grp.chargetype \ No newline at end of file +ON pvt.id = grp.id AND pvt.date = grp.date AND pvt.runID = grp.runId AND pvt.method = grp.method AND pvt.createdby = grp.createdby \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/measurementsMisc.sql b/onprc_ehr/resources/queries/study/measurementsMisc.sql index bb5c47f84..b2bf6cfd9 100644 --- a/onprc_ehr/resources/queries/study/measurementsMisc.sql +++ b/onprc_ehr/resources/queries/study/measurementsMisc.sql @@ -20,7 +20,8 @@ SELECT m.tissue, m.measurement1, m.measurement2, - m.measurement3 + m.measurement3, + m.remark from study.measurements m where m.tissue NOT IN (SELECT code FROM ehr_lookups.snomed_subset_codes sc WHERE sc.primaryCategory = 'Measurements') diff --git a/onprc_ehr/resources/queries/study/measurementsPivotedBody.sql b/onprc_ehr/resources/queries/study/measurementsPivotedBody.sql index 63982f4a0..9f5161835 100644 --- a/onprc_ehr/resources/queries/study/measurementsPivotedBody.sql +++ b/onprc_ehr/resources/queries/study/measurementsPivotedBody.sql @@ -19,11 +19,12 @@ select m.id, m.date, m.tissue, - max(m.measurement) as value + max(m.measurement) as value, + m.remark FROM study.measurementsPivotedRawData m WHERE m.categories like '%Body%' and m.measurementNo = '1' -group by m.id, m.date, m.tissue, m.parentid +group by m.id, m.date, m.tissue, m.parentid, m.remark pivot value by tissue \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/measurementsPivotedFetal.sql b/onprc_ehr/resources/queries/study/measurementsPivotedFetal.sql index 3baa82232..981b44e3a 100644 --- a/onprc_ehr/resources/queries/study/measurementsPivotedFetal.sql +++ b/onprc_ehr/resources/queries/study/measurementsPivotedFetal.sql @@ -19,11 +19,12 @@ select m.id, m.date, m.tissue, - max(m.measurement) as value + max(m.measurement) as value, + m.remark FROM study.measurementsPivotedRawData m WHERE m.categories like '%Fetal%' and m.measurementNo = '1' -group by m.id, m.date, m.tissue, m.parentid +group by m.id, m.date, m.tissue, m.parentid, m.remark pivot value by tissue \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/measurementsPivotedHeart.sql b/onprc_ehr/resources/queries/study/measurementsPivotedHeart.sql index c0633819c..83315498c 100644 --- a/onprc_ehr/resources/queries/study/measurementsPivotedHeart.sql +++ b/onprc_ehr/resources/queries/study/measurementsPivotedHeart.sql @@ -19,11 +19,12 @@ select m.id, m.date, m.tissue, - max(m.measurement) as value + max(m.measurement) as value, + m.remark FROM study.measurementsPivotedRawData m WHERE m.categories like '%Heart%' and m.measurementNo = '1' -group by m.id, m.date, m.tissue, m.parentid +group by m.id, m.date, m.tissue, m.parentid, m.remark pivot value by tissue \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/measurementsPivotedPlacental.sql b/onprc_ehr/resources/queries/study/measurementsPivotedPlacental.sql index a157ddd4b..dd695b4c8 100644 --- a/onprc_ehr/resources/queries/study/measurementsPivotedPlacental.sql +++ b/onprc_ehr/resources/queries/study/measurementsPivotedPlacental.sql @@ -19,11 +19,12 @@ select m.id, m.date, m.label as tissue, - max(m.measurement) as value + max(m.measurement) as value, + m.remark FROM study.measurementsPivotedRawData m WHERE m.categories like '%Placental%' -group by m.id, m.date, m.label, m.parentid +group by m.id, m.date, m.label, m.parentid, m.remark pivot value by tissue \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/measurementsPivotedRawData.sql b/onprc_ehr/resources/queries/study/measurementsPivotedRawData.sql index 47b14a15c..43b16794a 100644 --- a/onprc_ehr/resources/queries/study/measurementsPivotedRawData.sql +++ b/onprc_ehr/resources/queries/study/measurementsPivotedRawData.sql @@ -25,6 +25,7 @@ SELECT m0.measurementNo, m0.measurement, m0.parentid, + m0.remark, (SELECT group_concat(distinct sc.secondaryCategory) as expr FROM ehr_lookups.snomed_subset_codes sc WHERE sc.primaryCategory = 'Measurements' and m0.snomed = sc.code) as categories FROM ( @@ -36,7 +37,8 @@ SELECT m.tissue as snomed, '1' as measurementNo, m.measurement1 as measurement, - m.parentid + m.parentid, + m.remark from study.measurements m where measurement1 is not null @@ -50,7 +52,8 @@ select m.tissue as snomed, '2' as measurementNo, m.measurement2 as measurement, - m.parentid + m.parentid, + m.remark from study.measurements m where measurement2 is not null @@ -64,7 +67,8 @@ select m.tissue as snomed, '3' as measurementNo, m.measurement3 as measurement, - m.parentid + m.parentid, + m.remark from study.measurements m where measurement3 is not null diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.query.xml b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.query.xml new file mode 100644 index 000000000..6dc12a515 --- /dev/null +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.query.xml @@ -0,0 +1,11 @@ + + + + + Most Recent Observations For Behavior Case + oOservations +
+
+ +
+
diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql new file mode 100644 index 000000000..0de786a9d --- /dev/null +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql @@ -0,0 +1,12 @@ + +--- Created: 8-23-2018 R.Blasa +select a.id,a.date,a.reviewdate, +a.isactive, +a.allproblemcategories, +a.caseHistory, +b.observations + from study.cases a, mostrecentobservationsforcase b +where a.id = b.id +and a.objectid = b.caseid +and a.category = 'Behavior' +and a.isopen = true \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/.qview.xml b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/.qview.xml new file mode 100644 index 000000000..ccfd1d520 --- /dev/null +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/.qview.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml new file mode 100644 index 000000000..c7fc1db44 --- /dev/null +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/pairingEvents.query.xml b/onprc_ehr/resources/queries/study/pairingEvents.query.xml new file mode 100644 index 000000000..0f19fd363 --- /dev/null +++ b/onprc_ehr/resources/queries/study/pairingEvents.query.xml @@ -0,0 +1,39 @@ + + + + + Pairing Summary + + + + + + + + + + + 100 + + + 100 + + + + + 100 + + + Other Ids + + + + + + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/pairingEvents.sql b/onprc_ehr/resources/queries/study/pairingEvents.sql new file mode 100644 index 000000000..2359ca5ca --- /dev/null +++ b/onprc_ehr/resources/queries/study/pairingEvents.sql @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +SELECT + p.Id, + (SELECT group_concat(distinct p2.Id, chr(10)) FROM study.pairings p2 WHERE p.Id != p2.id AND p.pairId = p2.pairId) as otherIds, + p.pairid, + p.date, + p.lowestCage, + p.room, + p.cage, + p.eventType, + p.goal, + p.observation, + p.outcome, + p.separationreason, + p.remark, + p.remark2, + p.enddate, + p.endeventType, + p.performedby, + p.taskid, + TIMESTAMPDIFF('SQL_TSI_DAY', p.date, coalesce(p.enddate,curdate())) as duration, + p.qcstate + +FROM study.pairings p +where not (p.eventtype in ('General Comment', 'Pair monitor')) diff --git a/onprc_ehr/resources/queries/study/pairingEvents/.qview.xml b/onprc_ehr/resources/queries/study/pairingEvents/.qview.xml new file mode 100644 index 000000000..ed72dc87c --- /dev/null +++ b/onprc_ehr/resources/queries/study/pairingEvents/.qview.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/queries/study/pairingSummary.query.xml b/onprc_ehr/resources/queries/study/pairingSummary.query.xml index 798fd1333..103bd5f73 100644 --- a/onprc_ehr/resources/queries/study/pairingSummary.query.xml +++ b/onprc_ehr/resources/queries/study/pairingSummary.query.xml @@ -1,20 +1,39 @@ - - - - Pairing Summary - - - - - - - - - Other Ids - - -
-
-
+ + + + Pairing Summary + + + + + + + + + + + 100 + + + 100 + + + + + 100 + + + Other Ids + + + + + + + + +
+
+
diff --git a/onprc_ehr/resources/queries/study/pairingSummary.sql b/onprc_ehr/resources/queries/study/pairingSummary.sql index 32e04c463..a670ae47f 100644 --- a/onprc_ehr/resources/queries/study/pairingSummary.sql +++ b/onprc_ehr/resources/queries/study/pairingSummary.sql @@ -15,7 +15,8 @@ */ SELECT p.Id, - (SELECT group_concat(distinct p2.Id, chr(10)) FROM study.pairings p2 WHERE p.Id != p2.id AND p.pairId = p2.pairId) as otherIds, + (SELECT group_concat(distinct p2.Id, chr(10)) FROM study.pairings p2 WHERE p.Id != p2.id AND p.pairId = p2.pairId) as otherIds, + p.pairid, p.date, p.lowestCage, p.room, @@ -26,8 +27,13 @@ SELECT p.outcome, p.separationreason, p.remark, + p.remark2, + p.enddate, + p.endeventType, p.performedby, p.taskid, + TIMESTAMPDIFF('SQL_TSI_DAY', p.date, coalesce(p.enddate,curdate())) as duration, p.qcstate FROM study.pairings p + diff --git a/onprc_ehr/resources/queries/study/pairingSummary/.qview.xml b/onprc_ehr/resources/queries/study/pairingSummary/.qview.xml index 05c69057d..ed72dc87c 100644 --- a/onprc_ehr/resources/queries/study/pairingSummary/.qview.xml +++ b/onprc_ehr/resources/queries/study/pairingSummary/.qview.xml @@ -1,17 +1,24 @@ + - + - - + + + + + + - + + + diff --git a/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml b/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml new file mode 100644 index 000000000..3aca93970 --- /dev/null +++ b/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml @@ -0,0 +1,39 @@ + + + + + Pairing Summary Comments + + + + + + + + + + + 100 + + + 100 + + + 100 + + + + + Other Ids + + + + + + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/pairingSummaryComments.sql b/onprc_ehr/resources/queries/study/pairingSummaryComments.sql new file mode 100644 index 000000000..8f961e72e --- /dev/null +++ b/onprc_ehr/resources/queries/study/pairingSummaryComments.sql @@ -0,0 +1,24 @@ +SELECT + p.Id, + (SELECT group_concat(distinct p2.Id, chr(10)) FROM study.pairings p2 WHERE p.Id != p2.id AND p.pairId = p2.pairId) as otherIds, + p.pairid, + p.date, + p.lowestCage, + p.room, + p.cage, + p.eventType, + p.goal, + p.observation, + p.outcome, + p.separationreason, + p.remark, + p.remark2, + p.enddate, + p.endeventType, + p.performedby, + p.taskid, + TIMESTAMPDIFF('SQL_TSI_DAY', p.date, coalesce(p.enddate,curdate())) as duration, + p.qcstate + +FROM study.pairings p +where p.eventtype in ('General Comment', 'Pair monitor') \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/pairingSummaryComments/.qview.xml b/onprc_ehr/resources/queries/study/pairingSummaryComments/.qview.xml new file mode 100644 index 000000000..f19f9408f --- /dev/null +++ b/onprc_ehr/resources/queries/study/pairingSummaryComments/.qview.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/queries/study/pairings/.qview.xml b/onprc_ehr/resources/queries/study/pairings/.qview.xml index c7dae903d..b4ddd890d 100644 --- a/onprc_ehr/resources/queries/study/pairings/.qview.xml +++ b/onprc_ehr/resources/queries/study/pairings/.qview.xml @@ -6,11 +6,14 @@ + + + + - diff --git a/onprc_ehr/resources/queries/study/pregnancyGestation.sql b/onprc_ehr/resources/queries/study/pregnancyGestation.sql index b07f05eb3..82e0aecaf 100644 --- a/onprc_ehr/resources/queries/study/pregnancyGestation.sql +++ b/onprc_ehr/resources/queries/study/pregnancyGestation.sql @@ -18,7 +18,7 @@ SELECT m.id, m.date, m.gestation_days as gestation_days, -TIMESTAMPADD('SQL_TSI_DAY',(p.Gestation - m.gestation_days), curdate()) as ExpectedDelivery, +TIMESTAMPADD('SQL_TSI_DAY',(p.Gestation - m.gestation_days), m.date) as ExpectedDelivery, m.QCState FROM study.pregnancyConfirmation m diff --git a/onprc_ehr/resources/queries/study/processingSerology.sql b/onprc_ehr/resources/queries/study/processingSerology.sql index f908763c8..075cad4f2 100644 --- a/onprc_ehr/resources/queries/study/processingSerology.sql +++ b/onprc_ehr/resources/queries/study/processingSerology.sql @@ -65,7 +65,7 @@ SELECT END as isSRVCurrent, --all Jmacs and all non-SPF cynos CASE - WHEN (d.Id.age.ageInDays > 180 AND ((spf.Id IS NULL AND d.species = 'CYNOMOLGUS MACAQUE') OR d.species = 'JAPANESE MACAQUE')) THEN true + WHEN (d.Id.age.ageInDays > 180 AND ((spf.Id IS NULL AND (d.species = 'CYNOMOLGUS MACAQUE' OR d.species = 'RHESUS MACAQUE')) OR d.species = 'JAPANESE MACAQUE')) THEN true ELSE false END as isSRVRequired, diff --git a/onprc_ehr/resources/queries/study/treatmentSchedule.sql b/onprc_ehr/resources/queries/study/treatmentSchedule.sql index df0911113..6a0e2e993 100644 --- a/onprc_ehr/resources/queries/study/treatmentSchedule.sql +++ b/onprc_ehr/resources/queries/study/treatmentSchedule.sql @@ -87,8 +87,10 @@ JOIN study."Treatment Orders" t1 --NOTE: should the enddate consider date/time? ON (dr.dateOnly >= t1.dateOnly and dr.dateOnly <= t1.enddateCoalesced AND --technically the first day of the treatment is day 1, not day 0 - mod(CAST(timestampdiff('SQL_TSI_DAY', CAST(t1.dateOnly as timestamp), dr.dateOnly) as integer), t1.frequency.intervalindays) = 0 - ) + ( (mod(CAST(timestampdiff('SQL_TSI_DAY', CAST(t1.dateOnly as timestamp), dr.dateOnly) as integer), t1.frequency.intervalindays) = 0 And t1.frequency.intervalindays is not null And t1.frequency.dayofweek is null ) + + OR (t1.frequency.dayofweek is not null And t1.frequency.intervalindays is null And dr.DayOfWeek in (select k.value from onprc_ehr.Frequency_DayofWeek k where k.FreqKey = t1.frequency.rowid ) ) ) + ) LEFT JOIN ehr.treatment_times tt ON (tt.treatmentid = t1.objectid) LEFT JOIN ehr_lookups.treatment_frequency_times ft ON (ft.frequency = t1.frequency.meaning AND tt.rowid IS NULL) @@ -110,7 +112,8 @@ WHERE t1.date is not null ) s ON (s.animalid = d.id) -WHERE d.calculated_status = 'Alive' +WHERE (d.lastDayatCenter Is Null or d.lastDayAtCenter > s.enddate) + --account for date/time in schedule and s.date >= s.startDate and s.date <= s.enddate \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql new file mode 100644 index 000000000..e63d2705f --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * This stored Procedure is part of the eIACUC ETL process and is being added her to create the Stored Procedures in the + * SQL 2014 DB for Labkey-gj + */ + +GO +/****** Object: StoredProcedure [onprc_ehr].[etl1_eIACUCtoPRIMEProcessing] Script Date: 2/7/2018 2:01:46 PM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +Create PROCEDURE onprc_ehr.etl.Step1eIACUCtoPRIMEProcessing + +AS + + + Begin + + Update [onprc_ehr].[PRIME_VIEW_PROTOCOL_Processing] + set modifiedby = 000,modified = GetDate() + where modified is Null + + + + INSERT INTO [onprc_ehr].[PRIME_VIEW_PROTOCOL_Processing] + ( + [Protocol_ID] + ,[Template_OID] + ,[Protocol_OID] + ,[Protocol_Title] + ,[PI_ID] + ,[PI_First_Name] + ,[PI_Last_Name] + ,[PI_Email] + ,[PI_Phone] + ,[USDA_Level] + ,[ProcessDate] + ,[Approval_Date] + ,[Annual_Update_Due] + ,[Three_year_Expiration] + ,[Last_Modified] + ,created + ,createdby + ,recordStatus + ,PPQ_Numbers + ,PROTOCOL_State + + + ) + Select + Distinct + e.Protocol_ID, + e.Template_OID, + CONVERT(BINARY(16),e.Protocol_OID,2) as Protocol_OID, + e.Protocol_Title, + e.PI_ID, + e.PI_First_Name, + e.PI_Last_Name, + e.PI_Email, + e.PI_Phone, + e.USDA_Level, + GetDate () as ProcessDate, + e.Approval_Date, + e.Annual_Update_Due, + e.Three_year_Expiration, + e.Last_Modified, + GetDate(), + 1011, + + Case + When e.protocol_ID in + (Select e1.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e1 left outer join onprc_ehr.protocol p on p.external_id = e1.protocol_id where p.external_ID is Null) then 'new Record' + --in the update state we look at each possible area for change + When e.protocol_ID in + (Select e1.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e1 + left outer join onprc_ehr.protocol p on p.external_id = e1.protocol_id + where e1.Template_OID <> p.template_oid) then 'Update TemplateOID' + When e.protocol_ID in + (Select e2.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e2 + left outer join onprc_ehr.protocol p on p.external_id = e2.protocol_id + where e2.PPQ_numbers <> p.PPQ_Numbers) then 'Update PPQ Change' + When e.protocol_ID in + (Select e3.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e3 + left outer join onprc_ehr.protocol p on p.external_id = e3.protocol_id + where e3.Protocol_State <> p.PROTOCOL_State) then 'Update Protocol State' + When e.protocol_ID in + (Select e4.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e4 + left outer join onprc_ehr.protocol p on p.external_id = e4.protocol_id + where e4.Protocol_Title <> p.title) then 'Update Protocol Title' + else 'No Change' + End as RecordStatus + ,e.PPQ_Numbers + ,e.PROTOCOL_State + + from [onprc_ehr].[PRIME_VIEW_PROTOCOLS] e + + + + + If @@Error <> 0 + GoTo Err_Proc + + + + + + Return 0 + + Err_Proc: Return 1 + + + + + END \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.397-12.398.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.397-12.398.sql new file mode 100644 index 000000000..6117599d8 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.397-12.398.sql @@ -0,0 +1,49 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.animalGroups Dataset which is populated by the ETL Process + * + */ +CREATE TABLE [onprc_ehr].[PRIME_VIEW_ANIMAL_GROUPS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Parent_Protocol] [varchar](255) NOT NULL, + [Group_ID] [varchar](255) NULL, + [Group_Name] [varchar](255) NULL, + [Species] [varchar](255) NULL, + [SPF_Status] [varchar](255) NULL, + [Weight_Start] [varchar](255) NULL, + [Weight_End] [varchar](255) NULL, + [Age_Start] [varchar](255) NULL, + [Age_End] [varchar](255) NULL, + [Gender] [varchar](255) NULL, + [Number_of_Animals_Max] [int] NULL, + [Non_Standard_Housing_Types] [nvarchar](max) NULL, + [Non_Standard_Housing_Description] [ntext] NULL, + [Non_Standard_Housing_Frequency_and_Duration] [ntext] NULL, + [Non_Standard_Housing_Monitoring] [ntext] NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL, + [Restraint] [nvarchar](max) NULL, + [Nutritional_Manipulation_Description] [ntext] NULL, + [Nutritional_Manipulation_Adverse_Consequences] [nvarchar](255) NULL, + [Nutritional_Manipulation_Health_Assessment] [nchar](10) NULL, + [Non_Pharmaceutical_Grade_Drug_Use] [ntext] NULL, + [Food_Withheld] [int] NULL, + [Water_Withheld] [int] NULL, + [Food_Water_Withheld_Description] [ntext] NULL, + [Food_Water_Withheld_Justification] [ntext] NULL, + [Food_Water_Withheld_Adverse_Consequences] [ntext] NULL, + [Death_As_Endpoint_Number_of_Animals] [nvarchar](255) NULL, + [Death_As_Endpoint_Justification] [ntext] NULL +) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.398-12.399.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.398-12.399.sql new file mode 100644 index 000000000..53be17cb1 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.398-12.399.sql @@ -0,0 +1,26 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.IBC_Numberss Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[PRIME_VIEW_IBC_NUMBERS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Animal_Group] [varchar](255) NOT NULL, + [IBC_Registration_Number] [varchar](255) NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL +) ON [PRIMARY] +GO \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.399-12.400.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.399-12.400.sql new file mode 100644 index 000000000..a54bba27d --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.399-12.400.sql @@ -0,0 +1,32 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_NON_SURGICAL_PROCS Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[PRIME_VIEW_NON_SURGICAL_PROCS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Animal_Group] [varchar](255) NOT NULL, + [NS_Procedure_Name] [varchar](255) NULL, + [Standard_Procedure] [int] NULL, + [Iterations] [int] NULL, + [Deviation] [int] NULL, + [Deviation_Description] [varchar](255) NULL, + [Recovery_Days] [int] NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL +) ON [PRIMARY] +GO + diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.400-12.401.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.400-12.401.sql new file mode 100644 index 000000000..152e9a05b --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.400-12.401.sql @@ -0,0 +1,42 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_PROTOCOL_Processing Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[PRIME_VIEW_PROTOCOL_Processing]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Protocol_ID] [varchar](255) NOT NULL, + [Template_OID] [varchar](32) NULL, + [Protocol_OID] [binary](16) NULL, + [Protocol_Title] [varchar](255) NULL, + [PI_ID] [varchar](255) NULL, + [PI_First_Name] [varchar](255) NULL, + [PI_Last_Name] [varchar](255) NULL, + [PI_Email] [varchar](255) NULL, + [PI_Phone] [varchar](255) NULL, + [USDA_Level] [varchar](255) NULL, + [ProcessDate] [datetime] NULL, + [Approval_Date] [datetime] NULL, + [Annual_Update_Due] [datetime] NULL, + [Three_year_Expiration] [datetime] NULL, + [Last_Modified] [datetime] NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL, + [recordstatus] [nchar](25) NULL, + [PROTOCOL_STATE] [varchar](100) NULL, + [PPQ_Numbers] [varchar](255) NULL +) ON [PRIMARY] +GO \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.401-12.402.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.401-12.402.sql new file mode 100644 index 000000000..f791e5a77 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.401-12.402.sql @@ -0,0 +1,41 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_PROTOCOLS Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[PRIME_VIEW_PROTOCOLS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Protocol_ID] [varchar](255) NOT NULL, + [Template_OID] [varchar](32) NULL, + [Protocol_OID] [varchar](255) NULL, + [Protocol_Title] [varchar](255) NULL, + [PI_ID] [varchar](255) NULL, + [PI_First_Name] [varchar](255) NULL, + [PI_Last_Name] [varchar](255) NULL, + [PI_Email] [varchar](255) NULL, + [PI_Phone] [varchar](255) NULL, + [USDA_Level] [varchar](255) NULL, + [Approval_Date] [datetime] NULL, + [Annual_Update_Due] [datetime] NULL, + [Three_year_Expiration] [datetime] NULL, + [Last_Modified] [datetime] NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL, + [PROTOCOL_State] [varchar](250) NULL, + [PPQ_Numbers] [varchar](255) NULL, + [Description] [varchar](255) NULL +) ON [PRIMARY] +GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.402-12.403.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.402-12.403.sql new file mode 100644 index 000000000..395d3a73c --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.402-12.403.sql @@ -0,0 +1,28 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_SURGICAL_PROCS Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[PRIME_VIEW_SURGICAL_PROCS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [OID] [int] NOT NULL, + [Animal_Group] [varchar](255) NOT NULL, + [Standard_Procedure] [int] NULL, + [Iterations] [int] NULL, + [Deviation] [int] NULL, + [Deviation_Description] [varchar](255) NULL, + [Recovery_Days] [int] NULL, + [Surgery_Name] [varchar](255) NULL +) ON [PRIMARY] +GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.403-12.404.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.403-12.404.sql new file mode 100644 index 000000000..69a9ac057 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.403-12.404.sql @@ -0,0 +1,43 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.project Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[project]( + [project] [int] NOT NULL, + [protocol] [varchar](200) NULL, + [account] [varchar](200) NULL, + [inves] [varchar](200) NULL, + [avail] [varchar](100) NULL, + [title] [varchar](200) NULL, + [research] [bit] NULL, + [reqname] [varchar](200) NULL, + [createdby] [int] NOT NULL, + [created] [datetime] NULL, + [modifiedby] [int] NOT NULL, + [modified] [datetime] NULL, + [contact_emails] [varchar](4000) NULL, + [startdate] [datetime] NULL, + [enddate] [datetime] NULL, + [inves2] [varchar](200) NULL, + [name] [varchar](100) NULL, + [investigatorId] [int] NULL, + [use_category] [varchar](100) NULL, + [alwaysavailable] [bit] NULL, + [shortname] [varchar](200) NULL, + [projecttype] [varchar](100) NULL, + [container] [uniqueidentifier] NULL, + [objectid] [uniqueidentifier] NOT NULL +) ON [PRIMARY] +GO \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.404-12.405.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.404-12.405.sql new file mode 100644 index 000000000..182784fc2 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.404-12.405.sql @@ -0,0 +1,46 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.protocol Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[protocol]( + [rowId] [int] IDENTITY(1,1) NOT NULL, + [protocol] [varchar](200) NOT NULL, + [inves] [varchar](200) NULL, + [approve] [datetime] NULL, + [description] [text] NULL, + [createdby] [int] NOT NULL, + [created] [datetime] NULL, + [modifiedby] [int] NOT NULL, + [modified] [datetime] NULL, + [maxanimals] [int] NULL, + [enddate] [datetime] NULL, + [title] [varchar](1000) NULL, + [usda_level] [varchar](100) NULL, + [external_id] [varchar](200) NULL, + [project_type] [varchar](200) NULL, + [ibc_approval_required] [bit] NULL, + [ibc_approval_num] [varchar](200) NULL, + [investigatorId] [int] NULL, + [last_modification] [datetime] NULL, + [first_approval] [datetime] NULL, + [container] [uniqueidentifier] NULL, + [objectid] [uniqueidentifier] NOT NULL, + [lastAnnualReview] [datetime] NULL, + [PROTOCOL_State] [varchar](250) NULL, + [PPQ_Numbers] [varchar](255) NULL, + [template_oid] [varchar](255) NULL, + [Restraint] [varchar](255) NULL +) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] +GO \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql new file mode 100644 index 000000000..b23ecde03 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql @@ -0,0 +1,126 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the Stored Procedure etl1_eIACUCtoPRIMEProcessing + * + */ + +USE [Labkey] +GO +/****** Object: StoredProcedure [onprc_ehr].[etl1_eIACUCtoPRIMEProcessing] Script Date: 2/7/2018 2:01:46 PM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE PROCEDURE [onprc_ehr.etl.Step1eIACUCtoPRIMEProcessing] + +AS + + + Begin + + Update [onprc_ehr].[PRIME_VIEW_PROTOCOL_Processing] + set modifiedby = 000,modified = GetDate() + where modified is Null + + + + INSERT INTO [onprc_ehr].[PRIME_VIEW_PROTOCOL_Processing] + ( + [Protocol_ID] + ,[Template_OID] + ,[Protocol_OID] + ,[Protocol_Title] + ,[PI_ID] + ,[PI_First_Name] + ,[PI_Last_Name] + ,[PI_Email] + ,[PI_Phone] + ,[USDA_Level] + ,[ProcessDate] + ,[Approval_Date] + ,[Annual_Update_Due] + ,[Three_year_Expiration] + ,[Last_Modified] + ,created + ,createdby + ,recordStatus + ,PPQ_Numbers + ,PROTOCOL_State + + + ) + Select + Distinct + e.Protocol_ID, + e.Template_OID, + CONVERT(BINARY(16),e.Protocol_OID,2) as Protocol_OID, + e.Protocol_Title, + e.PI_ID, + e.PI_First_Name, + e.PI_Last_Name, + e.PI_Email, + e.PI_Phone, + e.USDA_Level, + GetDate () as ProcessDate, + e.Approval_Date, + e.Annual_Update_Due, + e.Three_year_Expiration, + e.Last_Modified, + GetDate(), + 1011, + + Case + When e.protocol_ID in + (Select e1.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e1 left outer join onprc_ehr.protocol p on p.external_id = e1.protocol_id where p.external_ID is Null) then 'new Record' + --in the update state we look at each possible area for change + When e.protocol_ID in + (Select e1.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e1 + left outer join onprc_ehr.protocol p on p.external_id = e1.protocol_id + where e1.Template_OID <> p.template_oid) then 'Update TemplateOID' + When e.protocol_ID in + (Select e2.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e2 + left outer join onprc_ehr.protocol p on p.external_id = e2.protocol_id + where e2.PPQ_numbers <> p.PPQ_Numbers) then 'Update PPQ Change' + When e.protocol_ID in + (Select e3.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e3 + left outer join onprc_ehr.protocol p on p.external_id = e3.protocol_id + where e3.Protocol_State <> p.PROTOCOL_State) then 'Update Protocol State' + When e.protocol_ID in + (Select e4.protocol_ID from onprc_ehr.PRIME_VIEW_PROTOCOLS e4 + left outer join onprc_ehr.protocol p on p.external_id = e4.protocol_id + where e4.Protocol_Title <> p.title) then 'Update Protocol Title' + else 'No Change' + End as RecordStatus + ,e.PPQ_Numbers + ,e.PROTOCOL_State + + from [onprc_ehr].[PRIME_VIEW_PROTOCOLS] e + + + + + If @@Error <> 0 + GoTo Err_Proc + + + + + + Return 0 + + Err_Proc: Return 1 + + + + + END \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql new file mode 100644 index 000000000..db4199aa8 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql @@ -0,0 +1,126 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the Stored Procedure etl1s_eIACUCtoPublicAction + * + */ + +USE [Labkey] +GO +/****** Object: StoredProcedure [onprc_ehr].[etl.Step1A_eIACUCtoPublicAction] Script Date: 2/7/2018 2:04:29 PM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +Create PROCEDURE [onprc_ehr].[etl1_eIACUCtoPublicAction] + +AS + Begin + + + INSERT INTO [Labkey_Public].[dbo].[protocolEiacucActions] + ([objectid] + ,[DateEntered] + ,[actionType] + ,[Protocol_ID] + ,[Date_Modified] + ,[Protocol_OID] + ,[Template_OID] + ,[Protocol_Title] + ,[InvestigatorID] + ,[PI_ID] + ,[PI_First_Name] + ,[PI_Last_Name] + ,[PI_Email] + ,[PI_Phone] + ,[USDA_Level] + ,[Approval_Date] + ,[Annual_Update_Due] + ,[Three_year_Expiration] + ,[Last_Modified] + ,[createdby] + ,[created] + ,[modifiedby] + ,[modified] + ,[status] + ,[container] + ,[PPQ_Numbers] + ,[PROTOCOL_State] + ,[description] + ) + + + + Select + NewID(), + null , + Case When p.recordStatus like 'update%' then 'update' + + when p.recordStatus = 'New Record' then 'Insert New' + + End as ActionType + ,p.Protocol_ID + ,p.modified as Date_Modified + ,p.Protocol_OID + ,p.Template_OID + ,p.Protocol_Title + ,(Select i.rowID from onprc_ehr.investigators i where i.employeeID = p.pi_id and i.dateDisabled is null) as InvestigatorID + ,p.PI_ID + ,p.PI_First_Name + ,p.PI_Last_Name + ,p.PI_Email + ,p.PI_Phone + ,p.USDA_Level + ,p.Approval_Date + ,p.Annual_Update_Due + ,p.Three_year_Expiration + ,p.Last_Modified + ,p.createdby + ,p.created + , + Case + when p.modifiedby is null then 0000 else p.modifiedby end as modifiedBy, + Case + when p.modified is null then getDate() else p.modified end as modified, + + p.recordstatus + ,'CD17027B-C55F-102F-9907-5107380A54BE' + ,p.PPQ_Numbers + ,p.PROTOCOL_State + ,Case when p.recordStatus like 'update%' then ('Update from eIACUC ' + p.recordstatus) + End as description + + + FROM onprc_ehr.PRIME_VIEW_Protocol_processing p + + where + p.recordstatus not in ('processed','No Change') + + Update onprc_ehr.PRIME_VIEW_Protocol_processing + Set modified = GetDate(),recordStatus = 'processed', ProcessDate = GetDate() + where modified is null + + If @@Error <> 0 + GoTo Err_Proc + + + + + + Return 0 + + Err_Proc: Return 1 + + + + + END \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql new file mode 100644 index 000000000..89554b8cb --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql @@ -0,0 +1,54 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the Stored Procedure etl3_insertToEhr_Protocol + * + */ + +USE [Labkey] +GO +/****** Object: StoredProcedure [onprc_ehr].[etl3_insertToEhr_Protocol] Script Date: 2/7/2018 2:30:52 PM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE PROCEDURE [onprc_ehr].[etl3_insertToEhr_Protocol] + +AS + + Begin + + INSERT INTO [LABKEY].[onprc_ehr].[protocol] + ([protocol] ,[approve],[createdby],[created],[modifiedby],[modified],[title] + ,[usda_level],[external_id],[investigatorId],[last_modification],[objectid],container,PROTOCOL_State,PPQ_Numbers + ) + Select + Protocol_ID,Approval_Date,createdby,created,modifiedby,modified,Protocol_Title + ,USDA_Level,Protocol_ID,InvestigatorID,Last_Modified,NewID(),'CD17027B-C55F-102F-9907-5107380A54BE',Protocol_State,PPQ_Numbers + FROM [Labkey_Public].dbo.protocolEIACUCActions + Where actionType in ('update','Insert New') + And dateentered is null + + If @@Error <> 0 + GoTo Err_Proc + + Update [Labkey_Public].[dbo].[protocolEiacucActions] + set dateentered = getdate(), status = 'processed' + Where status not like ('processed') + And dateentered is null + + Return 0 + + Err_Proc: Return 1 + + + END \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql new file mode 100644 index 000000000..418eaa068 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql @@ -0,0 +1,61 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the Stored Procedure etl2_update_ehrProtocol + * + */ + +USE [Labkey] +GO +/****** Object: StoredProcedure [onprc_ehr].[etl2_update_ehrProtocol] Script Date: 2/7/2018 2:29:18 PM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE PROCEDURE [onprc_ehr].[etl2_update_ehrProtocol] + +AS + +Begin + +--reviews the current table and insures that there is only 1 record per protocol + + + + + Update prot + Set prot.enddate = getDate(), + prot.description = p.description + From onprc_ehr.protocol prot join [labkey_public].dbo.protocolEiacucActions p on prot.external_id = p.protocol_ID + where prot.enddate is null and p.dateEntered is Null + and prot.objectID in + (Select e.objectID from onprc_ehr.protocol e, [labkey_public].dbo.protocolEiacucActions p where e.external_ID = p.Protocol_ID and e.enddate is null and p.status like 'Update%') + + + If exists (Select * from [Labkey_Public].dbo.protocolEIACUCActions + where status = 'new import' + And dateentered is null) + + + If @@Error <> 0 + GoTo Err_Proc + + + +Return 0 + +Err_Proc: Return 1 + + + + +END \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.702-17.703.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.702-17.703.sql new file mode 100644 index 000000000..286c488cd --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.702-17.703.sql @@ -0,0 +1,24 @@ +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO +GO + + +CREATE TABLE [onprc_ehr].[AvailableBloodVolume]( + [datecreated] [datetime] NULL, + [id] [nvarchar](32) NULL, + [gender] [nvarchar](4000) NULL, + [species] [nvarchar](4000) NULL, + [yoa] [float] NULL, + [mostrecentweightdate] [datetime] NULL, + [weight] [float] NULL, + [calcmethod] [nvarchar](32) NULL, + [BCS] [float] NULL, + [BCSage] [int] NULL, + [previousdraws] [float] NULL, + [ABV] [float] NULL, + [dsrowid] [bigint] NOT NULL +) ON [PRIMARY] +GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.703-17.704.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.703-17.704.sql new file mode 100644 index 000000000..d0255f005 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.703-17.704.sql @@ -0,0 +1,16 @@ +CREATE TABLE onprc_ehr.Reference_StaffNames( + RowId INT IDENTITY(1,1)NOT NULL, + username varchar(100), + LastName varchar(100) NULL, + FirstName varchar(100) NULL, + displayname varchar(100) NULL, + Type varchar(100) NULL, + role varchar(100) NULL, + remark varchar(200) NULL, + SortOrder smallint NULL, + StartDate smalldatetime NULL, + DisableDate smalldatetime NULL + + CONSTRAINT pk_reference PRIMARY KEY (username) + +); \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.704-17.705.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.704-17.705.sql new file mode 100644 index 000000000..dad5b389f --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.704-17.705.sql @@ -0,0 +1,12 @@ +CREATE TABLE onprc_ehr.Frequency_DayofWeek( + RowId INT IDENTITY(1,1)NOT NULL, + FreqKey SMALLINT NULL, + value SMALLINT NULL, + Meaning varchar(400) NULL, + calenderType varchar(100) NULL, + Sort_order SMALLINT NULL, + DisableDate smalldatetime NULL + + CONSTRAINT pk_FreqWeek PRIMARY KEY (RowId) + +); \ No newline at end of file diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index c9560cca6..006d57127 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -62,6 +62,15 @@ exports.init = function(EHR){ }); }); + //Added : 12-19-2017 R.Blasa + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study','clinpathRuns', function(helper, scriptErrors, row, oldRow){ + helper.setScriptOptions({ + + allowFutureDates: false //Added: R.Blasa + + }); + }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'deaths', function(event, helper){ helper.setScriptOptions({ allowDatesInDistantPast: true @@ -181,6 +190,23 @@ exports.init = function(EHR){ } }); + //Added 8-27-2018 R.Blasa Create a new entry when housing condition, or housing type are modified + // EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_INSERT, 'ehr_lookups', 'rooms', function(helper, scriptErrors, row, oldRow){ + // + // if (row.room == oldRow.room && row.cage == oldRow.cage && (oldRow.housingCondition != row.housingCondition || oldRow.housingType != row.houstingType) ){ + // + // //Create a log entry for billing as result of changes mades to Room dataset + // var msg = triggerHelper.createHousingTyperecord(room, row.housingType,row.housingCondition); + // if (msg){ + // EHR.Server.Utils.addError(scriptErrors, 'housingCondition', msg, 'INFO'); + // } + // else { + // triggerHelper.createHousingTyperecord(row.Id, row.enddate, row.releaseCondition); + // } + // + // } + // }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_INSERT, 'study', 'assignment', function(helper, scriptErrors, row, oldRow){ //check number of allowed animals at assign/approve time. use different behavior than core EHR if (!helper.isETL() && !helper.isQuickValidation() && @@ -214,6 +240,13 @@ exports.init = function(EHR){ } }); + //Created: 1-17-2018 R.Blasa + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'ehr', 'snomed_tags', function(helper, scriptErrors, row, oldRow){ + if (row.Id && !row.code){ + EHR.Server.Utils.addError(scriptErrors, 'code', 'A snomed code is required to continue', 'WARN'); + } + }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'assignment', function(helper, scriptErrors, row, oldRow){ // note: if this is automatically generated from death/departure, allow an incomplete record // alerts will flag these @@ -280,12 +313,49 @@ exports.init = function(EHR){ EHR.Server.Utils.addError(scriptErrors, 'groupId', msg, 'INFO'); } } + //Added: 12-29-2017 R.Blasa + if (row.Id && !row.groupId){ + EHR.Server.Utils.addError(scriptErrors, 'groupId', 'A Group Id selection is required.', 'WARN'); + } }); + + //Modified: 10-13-2016 R.Blasa added arrival date parameter EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'birth', function(helper, errors, row, oldRow) { - //NOTE: we want to perform the birth updates if this row is becoming public, or if we're updating to set the dam for the first time - if (!helper.isValidateOnly() && (row._becomingPublicData || (oldRow && !oldRow.dam && EHR.Server.Security.getQCStateByLabel(row.QCStateLabel).PublicData && row.dam))) { - triggerHelper.doBirthTriggers(row.Id, row.date, row.dam || null, row.arrival_date || null, row.birth_condition || null, !!row._becomingPublicData); + //Modified: 3-20-2017 R.Blasa Fetal Prenatal updates + if (row.id && oldRow) + { + if (row.id && oldRow.birth_condition && oldRow.birth_condition == 'Fetus - Prenatal' && row.birth_condition && row.birth_condition != 'Fetus - Prenatal') + { + //Modified: 10-27-2017 + triggerHelper.doBirthTriggers(row.Id, row.date, row.dam || null, row.Arrival_Date || null, row.birth_condition || null,row.species || null, !!row._becomingPublicData); + + //Added: 6-26-2017 R.Blasa + //set active flag condition after changing status from Fetus Prenatal to Alive. (Needs to execute because it is no longer considered isBecomingPublic status) + triggerHelper.doBirthConditionAfterPrenatal(row.Id, row.date, row.dam || null, row.Arrival_Date || null, row.birth_condition || null, !!row._becomingPublicData); + + //Created housing when room location is provided + if (row.id && row.room) + { + helper.getJavaHelper().createHousingRecord(row.Id, row.date, null, row.room, (row.cage || null), (row.initialCond || null)); + } + //Added: 6-26-2017 R.Blasa + //if a weight is provided, we insert into the weight table: + if (row.weight && row.wdate) + { + helper.getJavaHelper().insertWeight(row.Id, row.wdate, row.weight); + } + + } + } + //Added: 6-27-2017 R,Blasa Process only + if (row.birth_condition != 'Fetus - Prenatal') + { + //NOTE: we want to perform the birth updates if this row is becoming public, or if we're updating to set the dam for the first time + if (!helper.isValidateOnly() && (row._becomingPublicData || (oldRow && !oldRow.dam && EHR.Server.Security.getQCStateByLabel(row.QCStateLabel).PublicData && row.dam))) + { + triggerHelper.doBirthTriggers(row.Id, row.date, row.dam || null, row.Arrival_Date || null, row.birth_condition || null, row.species || null, !!row._becomingPublicData); + } } }); @@ -358,9 +428,29 @@ exports.init = function(EHR){ } }); } + + //Added: 1-17-2018 R.Blasa disallow male id + if (row.dam ) + { + EHR.Server.Utils.findDemographics({ + participant: row.dam , + helper: helper, + scope: this, + callback: function (data) + { + if (data) + { + if (data['gender/origGender'] && data['gender/origGender'] != 'f') + EHR.Server.Utils.addError(scriptErrors, 'dam', 'The dam has to be female', 'ERROR'); + } + } + }); + + } }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'deaths', function(scriptErrors, helper, row, oldRow){ + //Modified: 6-8-2018 R.Blasa + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'deaths', function(helper, errors, row, oldRow){ if (row.Id && row.date){ //close assignment records. triggerHelper.closeActiveAssignmentRecords(row.Id, row.date, (row.cause || null)); @@ -436,6 +526,10 @@ exports.init = function(EHR){ else if (data.calculated_status != 'Alive' && !data.hasBirthRecord){ EHR.Server.Utils.addError(scriptErrors, 'enddate', 'This animal is not listed as alive, cannot enter an open ended housing record', 'WARN'); } + //Added: 6-14-2017 R.Blasa + else if (data.calculated_status == 'Dead' || data.calculated_status == 'Shipped'){ + EHR.Server.Utils.addError(scriptErrors, 'Id', 'This animal is deceased or shipped out, you are not allowed to make this changes to the housing record', 'WARN'); + } } } }); @@ -474,18 +568,25 @@ exports.init = function(EHR){ }); EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'arrival', function(helper, scriptErrors, row, oldRow){ - onprc_utils.doHousingCheck(EHR, helper, scriptErrors, triggerHelper, row, oldRow, 'initialRoom', 'initialCage', false); + //Don't process normally if Pending -- Modified: 4-25-2017 R.Blasa + var acquiValue = triggerHelper.retrieveAcquisitionType(row.acquisitionType); + if (row.id && acquiValue != 'Pending Arrival') + { + onprc_utils.doHousingCheck(EHR, helper, scriptErrors, triggerHelper, row, oldRow, 'initialRoom', 'initialCage', false); + } }); -// EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'Parentage', function(helper, errors, row, oldRow){ -// if (row.Id && row.parent && row.relationship && row.method && EHR.Server.Security.getQCStateByLabel(row.QCStateLabel).PublicData) { -// onprc_utils.updateParentage(row.Id, row.parent, row.relationship, row.method); -// } -// }); EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'arrival', function(scriptErrors, helper, row, oldRow) { - if (row.Id && row.date) { - triggerHelper.ensureQuarantineFlag(row.Id, row.date); + //Don't process normally if Pending -- Modified: 4-5-2017 R.Blasa + var acquiValue = triggerHelper.retrieveAcquisitionType(row.acquisitionType); + if (row.id && acquiValue != 'Pending Arrival') + { + if (row.Id && row.date) + { + console.log('Qurantine flag') + triggerHelper.ensureQuarantineFlag(row.Id, row.date); + } } }); @@ -493,6 +594,80 @@ exports.init = function(EHR){ onprc_utils.doHousingCheck(EHR, helper, scriptErrors, triggerHelper, row, oldRow, null, null, false); }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'arrival', function(helper, errors, row, oldRow) { + //Don't process normally if Pending -- Created: 4-25-2017 R.Blasa + if (row.id && oldRow) + { + var acquiValueOld = triggerHelper.retrieveAcquisitionType(oldRow.acquisitionType); + var acquiValue = triggerHelper.retrieveAcquisitionType(row.acquisitionType); + if (row.id && acquiValueOld == 'Pending Arrival' && acquiValue != 'Pending Arrival' && EHR.Server.Security.getQCStateByLabel(row.QCStateLabel).PublicData) + { + //Add Housing record if room provided + if (row.initialRoom) + { + helper.getJavaHelper().createHousingRecord(row.Id, row.date, null, row.initialRoom, (row.initialCage || null), (row.initialCond || null)); + } + + //Add Birth record + triggerHelper.onAnimalArrival_AddBirth(row.id, row); + + triggerHelper.ensureQuarantineFlag(row.Id, row.date); + + } + + } + + if(row.id) + { + //Update demographics records + EHR.Server.Utils.findDemographics({ + participant: row.id, + helper: helper, + scope: this, + callback: function (data) + { + data = data || {}; + + var obj = {}; + var hasUpdates = false; + + if (row.gender && row.gender != data.gender ) + { + obj.gender = row.gender; + hasUpdates = true; + } + + if (row.species && row.species != data.species ) + { + obj.species = row.species; + hasUpdates = true; + } + + if (row.geographic_origin && row.geographic_origin != data.geographic_origin ) + { + obj.geographic_origin = row.geographic_origin; + hasUpdates = true; + } + + if (row.birth && row.birth.getTime() != (data.birth ? data.birth.getTime() : 0)) + { + obj.birth = row.birth; + hasUpdates = true; + } + + + if (hasUpdates) + { + obj.Id = row.id; + var demographicsUpdates = [obj]; + helper.getJavaHelper().updateDemographicsRecord(demographicsUpdates); + } + + } + }); + } + }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'treatment_order', function(scriptErrors, helper, row, oldRow){ var fieldPairs = [ ['dosage_units', 'dosage'], @@ -561,8 +736,8 @@ exports.init = function(EHR){ if (helper.isETL() || helper.isValidateOnly()){ return; } - - if (row && oldRow && row.category != 'Research'){ + //Modified: 7-12-2017 R.blasa + if (row && oldRow ){ EHR.Assert.assertNotEmpty('triggerHelper is null', triggerHelper); var date = triggerHelper.onTreatmentOrderChange(row, oldRow); @@ -572,6 +747,20 @@ exports.init = function(EHR){ } }); + // //Added: 9-7-2018 R.Blasa + // EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.AFTER_UPSERT, 'study', 'encounters', function(helper, errors, row, oldRow) { + // //Create an immediate alert notification when this is created + // // if (row.id && row.procedureid == 2440) { + // if (row.id && row.procedureid == 2094) { + // //Update demographics records + // console.log("ASB Procedure Request Complete NOP " + row.procedureid); + // var msg = triggerHelper.sendASBProcedureNOPRequestNotification(row.id); + // if (msg){ + // EHR.Server.Utils.addError(scriptErrors, 'procedureid', msg, 'ERROR'); + // } + // } + // }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'clinremarks', function(scriptErrors, helper, row, oldRow){ if (helper.isETL() || helper.isValidateOnly()){ return; @@ -583,4 +772,22 @@ exports.init = function(EHR){ triggerHelper.replaceSoap(row.parentid); } }); + + + EHR.Server.TriggerManager.registerHandler(EHR.Server.TriggerManager.Events.INIT, function (event, helper) { + // Override the default EHR validation for project creation + EHR.Server.TriggerManager.unregisterAllHandlersForQueryNameAndEvent('ehr', 'project', EHR.Server.TriggerManager.Events.BEFORE_UPSERT); + + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'ehr', 'project', function (helper, scriptErrors, row, oldRow) { + var constraintHelper = org.labkey.ldk.query.UniqueConstraintHelper.create(LABKEY.Security.currentContainer.id, LABKEY.Security.currentUser.id, 'ehr', 'project_active', 'name'); + console.log("ONPRC insert handler"); + //enforce name unique + if (row.name) { + var isValid = constraintHelper.validateKey(row.name, oldRow ? (oldRow.name || null) : null); + if (!isValid) { + EHR.Server.Utils.addError(scriptErrors, 'name', 'There is already an old project with the name in ehr: ' + row.name, 'ERROR'); + } + } + }); + }); }; \ No newline at end of file diff --git a/onprc_ehr/resources/views/PE_ExamHistoryReportbyID.html b/onprc_ehr/resources/views/PE_ExamHistoryReportbyID.html new file mode 100644 index 000000000..59a56791b --- /dev/null +++ b/onprc_ehr/resources/views/PE_ExamHistoryReportbyID.html @@ -0,0 +1,63 @@ + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/PE_ExamHistoryReportbyID.view.xml b/onprc_ehr/resources/views/PE_ExamHistoryReportbyID.view.xml new file mode 100644 index 000000000..3c5ab2210 --- /dev/null +++ b/onprc_ehr/resources/views/PE_ExamHistoryReportbyID.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/animalHistory.html b/onprc_ehr/resources/views/animalHistory.html index 6f39260b4..6cc9068e0 100644 --- a/onprc_ehr/resources/views/animalHistory.html +++ b/onprc_ehr/resources/views/animalHistory.html @@ -7,27 +7,20 @@ return; Ext4.create('EHR.panel.AnimalHistoryPanel', { + + html: '**Please click the Update Report button if the program fails to display a report**', //Added: 11-17-2017 R.Blasa + defaultReport: ctx.DefaultAnimalHistoryReport, defaultTab: 'General', showFilterOptionsTitle: true, filterTypes: [{ xtype: 'ldk-singlesubjectfiltertype', inputValue: LDK.panel.SingleSubjectFilterType.filterName, - label: 'Single Animal', - aliasTable: { - schemaName: 'study', - queryName: 'demographics', - idColumn: 'Id' - } + label:'Single Animal' },{ - xtype: 'ehr-multianimalfiltertype', + xtype: 'onprc_ehr-multianimalfiltertype', inputValue: EHR.panel.MultiAnimalFilterType.filterName, - label: EHR.panel.MultiAnimalFilterType.label, - aliasTable: { - schemaName: 'study', - queryName: 'demographics', - idColumn: 'Id' - } + label: EHR.panel.MultiAnimalFilterType.label },{ xtype: 'ehr-locationfiltertype', inputValue: EHR.panel.LocationFilterType.filterName, diff --git a/onprc_ehr/resources/views/animalHistory.view.xml b/onprc_ehr/resources/views/animalHistory.view.xml index 2b220c511..c938780dc 100644 --- a/onprc_ehr/resources/views/animalHistory.view.xml +++ b/onprc_ehr/resources/views/animalHistory.view.xml @@ -5,7 +5,7 @@ - + diff --git a/onprc_ehr/resources/views/begin.html b/onprc_ehr/resources/views/begin.html index 102700d03..b1f3e37c6 100644 --- a/onprc_ehr/resources/views/begin.html +++ b/onprc_ehr/resources/views/begin.html @@ -48,7 +48,7 @@ style: 'font-weight: bold;' }, items: [ - {name: 'Browse All Datasets', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/datasets.view?'}, + {name: 'Browse All Datasets', url: '<%=contextPath%>/onprc_ehr' + ctx['EHRStudyContainer'] + '/datasets.view?'}, {name: 'Housing Queries', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/housingQueries.view?'}, {name: 'Protocol and Project Queries', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/projectQueries.view?'} ] @@ -122,7 +122,8 @@ style: 'font-weight: bold;' }, items: [ - {name: 'Enter Data / Task Review', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/enterData.view'}, +// Modified: 4-3-2017 R.Blasa Allow new method of presenting Necropsy entry screens + {name: 'Enter Data / Task Review', url: '<%=contextPath%>/onprc_ehr' + ctx['EHRStudyContainer'] + '/enterData.view'}, {name: 'Post Op Med Verification', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/dataEntryForm.view?formType=medsignoff'} ] @@ -133,9 +134,9 @@ style: 'font-weight: bold;' }, items: [ - {name: 'Manage Requests', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/serviceRequests.view'}, - //{name: 'ASB Services Request', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/dataEntryForm.view?formType=ASB Service Request'}, - //{name: 'Colony Services Request', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/dataEntryForm.view?formType=Colony Service Request'}, + // Modified: 7-18-2017 R.Blasa + {name: 'Manage Requests', url: '<%=contextPath%>/onprc_ehr' + ctx['EHRStudyContainer'] + '/serviceRequests.view'}, + {name: 'Request Labwork', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/dataEntryForm.view?formType=Labwork Request'} ] }] diff --git a/onprc_ehr/resources/views/datasets.html b/onprc_ehr/resources/views/datasets.html new file mode 100644 index 000000000..af46fd364 --- /dev/null +++ b/onprc_ehr/resources/views/datasets.html @@ -0,0 +1,96 @@ + diff --git a/onprc_ehr/resources/views/datasets.view.xml b/onprc_ehr/resources/views/datasets.view.xml new file mode 100644 index 000000000..cbe07b93a --- /dev/null +++ b/onprc_ehr/resources/views/datasets.view.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/enterData.html b/onprc_ehr/resources/views/enterData.html new file mode 100644 index 000000000..598366892 --- /dev/null +++ b/onprc_ehr/resources/views/enterData.html @@ -0,0 +1,14 @@ + diff --git a/onprc_ehr/resources/views/enterData.view.xml b/onprc_ehr/resources/views/enterData.view.xml new file mode 100644 index 000000000..7badacbee --- /dev/null +++ b/onprc_ehr/resources/views/enterData.view.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/onprc_ehr/resources/views/frontPage.html b/onprc_ehr/resources/views/frontPage.html new file mode 100644 index 000000000..d35883632 --- /dev/null +++ b/onprc_ehr/resources/views/frontPage.html @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/onprc_ehr/resources/views/frontPage.view.xml b/onprc_ehr/resources/views/frontPage.view.xml new file mode 100644 index 000000000..f33aa86c2 --- /dev/null +++ b/onprc_ehr/resources/views/frontPage.view.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/frontPage.webpart.xml b/onprc_ehr/resources/views/frontPage.webpart.xml new file mode 100644 index 000000000..96163b513 --- /dev/null +++ b/onprc_ehr/resources/views/frontPage.webpart.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/groupProcessing.html b/onprc_ehr/resources/views/groupProcessing.html index b5a680503..1165e0a94 100644 --- a/onprc_ehr/resources/views/groupProcessing.html +++ b/onprc_ehr/resources/views/groupProcessing.html @@ -72,13 +72,14 @@ var params = item.up('#processingBloodDrawsBtn').getUrlParams(); window.open(LABKEY.ActionURL.buildURL('query', 'executeQuery', null, params)) } - },{ - text: 'Download To Excel', - scope: this, - handler: function(item){ - var params = item.up('#processingBloodDrawsBtn').getUrlParams(); - window.open(LABKEY.ActionURL.buildURL('query', 'exportRowsXLSX', null, params)) - } +// Modified: 12-7-2018 R.Blasa Defaults to Open Browser since Export menu limits the size to 100 records +// },{ +// text: 'Download To Excel', +// scope: this, +// handler: function(item){ +// var params = item.up('#processingBloodDrawsBtn').getUrlParams(); +// window.open(LABKEY.ActionURL.buildURL('query', 'exportRowsXLSX', null, params)) +// } }] },{ html: '
Blood Needed For Viral Surveillance:', @@ -236,13 +237,13 @@ handler: function(item){ var params = item.up('#clinicalPeBtn').getUrlParams(); window.open(LABKEY.ActionURL.buildURL('query', 'executeQuery', null, params)) - } - },{ - text: 'Download To Excel', - scope: this, - handler: function(item){ - var params = item.up('#clinicalPeBtn').getUrlParams(); - window.open(LABKEY.ActionURL.buildURL('query', 'exportRowsXLSX', null, params)) +// } +// },{ +// text: 'Download To Excel', +// scope: this, +// handler: function(item){ +// var params = item.up('#clinicalPeBtn').getUrlParams(); +// window.open(LABKEY.ActionURL.buildURL('query', 'exportRowsXLSX', null, params)) } }] }] diff --git a/onprc_ehr/resources/views/printableReports.html b/onprc_ehr/resources/views/printableReports.html index 00eb3e928..89f4d6f7d 100644 --- a/onprc_ehr/resources/views/printableReports.html +++ b/onprc_ehr/resources/views/printableReports.html @@ -25,7 +25,8 @@ html: 'This page provides reports to be printed by room or area. After picking the location(s) using the drop downs below, ' + 'hit the \'Print\' buttons below to print any of the reports

NOTE:' + ' For most reports, leave rooms/areas blank to print all.
Vet control only applies to "Active by Clinical Cases by Vets". ' + - '
Breeding Group control only applies to "Weights Sheets by Breeding Groups".
', + '
Breeding Group control only applies to "Weights Sheets by Breeding Groups".' + + '
Enter Animal ID only applies to "Weights Sheets by Monkey ID".
', style: 'padding-bottom: 20px;' },{ xtype: 'ehr-areafield', @@ -84,6 +85,12 @@ autoLoad: true } + },{ + xtype:'textarea', //Added: 7-27-2017 R.Blasa + itemId: 'animalField', + width: 295, + height: 100, + fieldLabel: 'Enter Animal ID' },{ html: '', style: 'margin-bottom: 10px;' @@ -682,7 +689,7 @@ return; if (!Ext4.isEmpty(value)) - params.Groups = value; //params.rooms is the parameter name + params.Groups = value; Ext4.apply(params, { @@ -719,6 +726,91 @@ window.open(url); } }] + + },{ + html: '' + },{ + html: '
', + style: 'padding-top: 10px;', + colspan: 4 + + },{ + html: 'Weight Sheets by Monkey ID:' //Added: 7-27-2017 R.Blasa + },{ + style: 'padding-left: 5px;', + html: '' + },{ + xtype: 'button', + style: 'margin-left: 5px;', + text: 'Print Version', + border: true, + getUrlString: function(){ + var panel = this.up('#sheetPanel'); + var field = panel.down('#animalField'); + + var val = field.getValue() || []; + + + if (val){ + val = Ext4.String.trim(val); + val = val.replace(/[\s,;]+/g, ';'); + val = val.replace(/(^;|;$)/g, ''); + + val = val ? val.split(';') : []; + } + + if (!val){ + Ext4.Msg.alert('Error', 'Must enter at least one animal Id'); + return; + } + value = Ext4.isArray(val) ? val: [val]; + + var params = { + SessionId: LABKEY.Utils.getSessionID(), + HostName: location.hostname + + }; + if (!val) + return; + + if (!Ext4.isEmpty(value)) + params.AnimalID = val; + + + Ext4.apply(params, { + 'rs:ClearSession': true, + 'rs:Command': 'render' + }); + + var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); + var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); + ssrsFolder = '/' + ssrsFolder + '/' + 'WeightSheetsID'; + + url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); + return url; + }, + menu: [{ + text: 'Print', + handler: function(menu){ + var btn = menu.up('button'); + var url = btn.getUrlString(); + if (!url) + return; + + window.open(url); + } + },{ + text: 'Print To PDF', + handler: function(menu){ + var btn = menu.up('button'); + var url = btn.getUrlString(); + if (!url) + return; + + url += '&rs:Format=PDF'; + window.open(url); + } + }] },{ html: '' },{ diff --git a/onprc_ehr/resources/views/quickSearchonprc.html b/onprc_ehr/resources/views/quickSearchonprc.html index 194ceea8f..2e3c111c9 100644 --- a/onprc_ehr/resources/views/quickSearchonprc.html +++ b/onprc_ehr/resources/views/quickSearchonprc.html @@ -177,9 +177,13 @@ window.location = LABKEY.ActionURL.buildURL('ehr', 'projectDetails', ctx['EHRStudyContainer'], {project:value}); } },{ - html: '[View Active Projects] [View All Projects]', + html: '[View Active Projects] ' + + ' [View All Projects] ' + + ' [View Center Project To Alias]', colspan: 2 + },{ + html: 'IACUC Protocol:', style: 'padding-top: 10px;', colspan: 2 diff --git a/onprc_ehr/resources/views/serviceRequests.view.xml b/onprc_ehr/resources/views/serviceRequests.view.xml index 6e234cf19..9b8d147c5 100644 --- a/onprc_ehr/resources/views/serviceRequests.view.xml +++ b/onprc_ehr/resources/views/serviceRequests.view.xml @@ -1,7 +1,6 @@ - + - - + \ No newline at end of file diff --git a/onprc_ehr/resources/views/vetReview.html b/onprc_ehr/resources/views/vetReview.html index 584124ab2..3020e606f 100644 --- a/onprc_ehr/resources/views/vetReview.html +++ b/onprc_ehr/resources/views/vetReview.html @@ -1,103 +1,108 @@ \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js b/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js index c9fa5afbb..e7f66d517 100644 --- a/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js +++ b/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js @@ -138,7 +138,7 @@ EHR.DemographicsRecord = function(data){ }, getGeographicOrigin: function(){ - return data['geographic_origin']; + return data['geneticAncestry'] ? data['geneticAncestry'] + ' (Verified)' : data['geographic_origin']; }, getMostRecentWeight: function(){ @@ -190,14 +190,6 @@ EHR.DemographicsRecord = function(data){ } }, - getLastTBDate: function(){ - if (data['tb'] && data['tb'].length){ - var date = data['tb'][0]['MostRecentTBDate']; - if (date) - return LDK.ConvertUtils.parseDate(date); - } - }, - getRecentWeights: function(){ return data['weights']; }, diff --git a/onprc_ehr/resources/web/onprc_ehr/buttons/ClinicalActionsButton.js b/onprc_ehr/resources/web/onprc_ehr/buttons/ClinicalActionsButton.js index 36fcc20f6..4104f0c4d 100644 --- a/onprc_ehr/resources/web/onprc_ehr/buttons/ClinicalActionsButton.js +++ b/onprc_ehr/resources/web/onprc_ehr/buttons/ClinicalActionsButton.js @@ -77,7 +77,7 @@ Ext4.define('onprc_ehr.buttons.ClinicalActionsButton', { return; } - Ext4.create('EHR.window.ManageCasesWindow', { + Ext4.create('ONPRC_EHR.window.ManageCasesWindow', { animalId: animalId }).show(); } diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js new file mode 100644 index 000000000..1e771dfac --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js @@ -0,0 +1,138 @@ + + +//Created: 12-18-2017 R.Blasa + +Ext4.define('ONPRC_EHR.data.sources.BehaviorExamStoreCollection', { + extend: 'EHR.data.TaskStoreCollection', + + constructor: function(){ + this.callParent(arguments); + + this.mon(EHR.DemographicsCache, 'casecreated', this.onCaseCreated, this); + }, + + onCaseCreated: function(id, category, caseId){ + if (category != 'Clinical') + return; + + //NOTE: if we opened a case from this form, tag the SOAP note + var rec = this.getRemarksRec(); + if (rec && id == rec.get('Id')){ + if (!rec.get('caseid')){ + rec.set('caseid', caseId); + } + } + }, + + setClientModelDefaults: function(model){ + var vals = this.getDefaultValues(); + if (!Ext4.Object.isEmpty(vals)){ + var toSet = {}; + + if (model.fields.get('Id') != null){ //Added : Testing R. Blasa + toSet.Id = vals.Id; + toSet.date = vals.date; + + } + if (model.fields.get('caseid') != null){ + toSet.caseid = vals.caseid; + } + + if (!Ext4.isEmpty(toSet)){ + model.suspendEvents(); + model.set(toSet); + model.resumeEvents(); + } + } + + return this.callParent([model]); + }, + + getRemarksStore: function(){ + if (this.remarkStore){ + return this.remarkStore; + } + + this.remarkStore = this.getClientStoreByName('Clinical Remarks'); + LDK.Assert.assertNotEmpty('Unable to find clinical remarks store in ClinicalReportStoreCollection', this.remarkStore); + + return this.remarkStore; + }, + + getRemarksRec: function(){ + var remarkStore = this.getRemarksStore(); + if (remarkStore){ + LDK.Assert.assertTrue('More than 1 record found in Clinical remarks store, actual: ' + remarkStore.getCount(), remarkStore.getCount() <= 1); + if (remarkStore.getCount() == 1){ + return remarkStore.getAt(0); + } + } + }, + + getDefaultValues: function(){ + var rec = this.getRemarksRec(); + if (rec){ + return { + Id: rec.get('Id'), + date:rec.get('date'), //Added R.Blasa + caseid: rec.get('caseid') + } + } + + return null; + }, + + onClientStoreUpdate: function(){ + this.doUpdateRecords(); + this.callParent(arguments); + }, + + doUpdateRecords: function(){ + var newValues = this.getDefaultValues() || {}; + var cacheKey = newValues ? (newValues.Id + '||' + newValues.caseid) : null; + + if (cacheKey !== this._cachedKey){ + var remarkStore = this.getRemarksStore(); + this.clientStores.each(function(cs){ + if (cs.storeId == remarkStore.storeId){ + return; + } + + var toSet = {}; + + if (cs.getFields().get('Id') != null){ + toSet.Id = newValues.Id; + } + if (cs.getFields().get('caseid') != null){ + toSet.caseid = newValues.caseid; + } + + if (Ext4.Object.isEmpty(toSet)){ + return; + } + + var storeChanged = false; + cs.suspendEvents(); + cs.each(function(rec){ + var needsUpdate = false; + for (var field in toSet){ + if (toSet[field] !== rec.get(field)){ + needsUpdate = true; + } + } + + if (needsUpdate){ + storeChanged = true; + rec.set(toSet); + } + }, this); + cs.resumeEvents(); + + if (storeChanged) + cs.fireEvent('datachanged', cs); + }, this); + } + + this._cachedKey = cacheKey; + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js index dc11d2d20..96ca24c50 100644 --- a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js @@ -30,22 +30,161 @@ EHR.model.DataModelManager.registerMetadata('Default', { } } + }, + + //Added: 12-27-2017 R.Blasa + 'study.Arrival': { + date: { + xtype: 'xdatetime', + allowBlank: false, + extFormat: LABKEY.extDefaultDateTimeFormat, + columnConfig: { + width: 150 + } + }, + //Added: 5-3-2018 R.Blasa + acquisitionType: { + hidden: false, + allowBlank: false + } + }, + + //Added: 12-26-2017 R.Blasa + 'study.Assignment': { + + date: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 100 + } + }, + enddate: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 100 + } + }, + + projectedRelease: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 100 + } + }, + + projectedReleaseCondition: { + columnConfig: { + width: 200 + } + }, + releaseCondition: { + columnConfig: { + width: 200 + } , + lookup: { + filterArray: [ + LABKEY.Filter.create('datedisabled', null, LABKEY.Filter.Types.ISBLANK) + + ] + + } + }, + + assignCondition: { + columnConfig: { + width: 200 + } + + }, + + + projectedRelease: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 100 + } + } + + }, + + 'study.weight': { + project: { + hidden: true + }, + account: { + hidden: true + }, + performedby: { + allowBlank: false, + lookup: { + schemaName: 'core', + queryName: 'users', + keyColumn: 'DisplayName', + displayColumn: 'DisplayName', + columns: 'UserId,DisplayName,FirstName,LastName', + sort: 'Type,DisplayName' + } + }, + + 'id/curlocation/location': { + shownInGrid: true + }, + remark: { + shownInGrid: true + }, + weight: { + allowBlank: false, + useNull: true, + editorConfig: { + allowNegative: false, + decimalPrecision: 4 + } + } + }, + //Added: 11-20-2017 R.blasa + + 'study.clinremarks': { + + CEG_Plan: { + formEditorConfig: { + xtype: 'onprc_ehr-CEG_Plantextarea' + }, + height: 52 + } + }, + + //Added: 12-27-2017 R.blasa + + 'study.flags': { + + RequestedBy: { + columnConfig: { + width: 100 + } + + }, + ScheduleNecropsy: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 150 + } + + }, + TargetEndDate: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 150 + } + } + } - // 'study.Assignment' : { - // Cohort: { - // xtype: 'onprc-cohortfield', - // editorConfig: { - // - // }, - // shownInGrid: true, - // useNull: true, - // columnConfig: { - // width: 500 - // } - // } - // } - // } }); diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/PathologyTissuesStoreCollection.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/PathologyTissuesStoreCollection.js new file mode 100644 index 000000000..64ddeed8e --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/PathologyTissuesStoreCollection.js @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +//Added 5-24-2017 R.Blasa +Ext4.define('onprc_ehr.data.sources.PathologyTissuesStoreCollection', { + extend: 'EHR.data.TaskStoreCollection', + + constructor: function(){ + this.callParent(arguments); + }, + + setClientModelDefaults: function(model){ + var vals = this.getDefaultValues(); + if (!Ext4.Object.isEmpty(vals)){ + var toSet = {}; + + if (model.fields.get('Id') != null){ + toSet.Id = vals.Id; + toSet.date = vals.date; + toSet.project = vals.project; + } + + + if (!Ext4.isEmpty(toSet)){ + model.suspendEvents(); + model.set(toSet); + model.resumeEvents(); + } + } + + return this.callParent([model]); + }, + + getRemarksStore: function(){ + if (this.remarkStore){ + return this.remarkStore; + } + + this.remarkStore = this.getClientStoreByName('encounters'); + LDK.Assert.assertNotEmpty('Unable to find Pathology tissue record store in PathologyTissuesReportStoreCollection', this.remarkStore); + + return this.remarkStore; + }, + + getRemarksRec: function(){ + var remarkStore = this.getRemarksStore(); + if (remarkStore){ + LDK.Assert.assertTrue('More than 1 record found in Pathology Tissues store, actual: ' + remarkStore.getCount(), remarkStore.getCount() <= 1); + if (remarkStore.getCount() == 1){ + return remarkStore.getAt(0); + } + } + }, + + getDefaultValues: function(){ + var rec = this.getRemarksRec(); + if (rec){ + return { + Id: rec.get('Id'), + date:rec.get('date'), + project:rec.get('project') + + } + } + + return null; + } + + +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/form/field/AnimalGroupFieldsCombo.js b/onprc_ehr/resources/web/onprc_ehr/form/field/AnimalGroupFieldsCombo.js new file mode 100644 index 000000000..ae1e67757 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/form/field/AnimalGroupFieldsCombo.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + * + * @cfg pairedWithRoomField. Note: if true, you must implement getRoomField(), which returns the cognate ehr-roomfield + */ +Ext4.define('ONPRC_EHR.form.field.AnimalGroupField', { + extend: 'Ext.ux.CheckCombo', + alias: 'widget.onprc_ehr-animalgroupfield', + + fieldLabel: 'Animal Group', + expandToFitContent: true, + nullCaption: '[Blank]', + editable: false, + typeAhead: true, + + initComponent: function(){ + Ext4.apply(this, { + displayField: 'name', + valueField: 'rowid', + queryMode: 'local', + store: Ext4.create('LABKEY.ext4.data.Store', { + schemaName: 'ehr', + queryName: 'animal_groups', + sort: 'name', + filterArray: [LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL)], + autoLoad: true + }) + }); + + this.callParent(arguments); + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/form/field/CEG_PlantextArea.js b/onprc_ehr/resources/web/onprc_ehr/form/field/CEG_PlantextArea.js new file mode 100644 index 000000000..3620e5e9d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/form/field/CEG_PlantextArea.js @@ -0,0 +1,201 @@ +/** + * Created: R.Blasa on 10/25/2017. + */ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +Ext4.define('ONPRC_EHR.form.field.CEG_PlantextArea', { + extend: 'Ext.form.field.TextArea', + alias: 'widget.onprc_ehr-CEG_Plantextarea', + + onAnimalChange: function(){ + this.updateDisplayEl(); + }, + + onRender : function(ct, position){ + this.callParent(arguments); + + this.wrap = this.inputEl.wrap({ + tag: 'div', + cls: 'x4-form-field-wrap' + }); + + this.linkDiv = this.wrap.createChild({ + tag: 'div', + style: 'vertical-align:top;' + }, this.inputEl); + + this.linkEl = this.linkDiv.createChild({ + tag: 'a', + cls: 'labkey-text-link', + html: (this.getValue() ? 'Copy Latest CEG_Plan' : 'Edit CEG_Plan') + }); + + var panel = this.up('ehr-formpanel'); + if (panel){ + this.mon(panel, 'bindrecord', this.onAnimalChange, this, {buffer: 100}); + } + else { + LDK.Utils.logToServer({ + message: 'Unable to find ehr-formpanel in PlanTextArea' + }) + } + + var dataEntryPanel = this.up('ehr-dataentrypanel'); + if (dataEntryPanel){ + this.mon(dataEntryPanel, 'animalchange', this.onAnimalChange, this, {buffer: 100}); + } + else { + LDK.Utils.logToServer({ + message: 'Unable to find ehr-dataentrypanel in PlanTextArea' + }) + } + + this.linkEl.on('click', this.copyMostRecentCEG_Plan, this); + this.setupMask(); + }, + + setupMask: function(){ + if (this.getValue()){ + this.showTextArea(); + return; + } + + this.inputEl.setVisibilityMode(Ext4.dom.AbstractElement.DISPLAY); + this.inputEl.setVisible(false); + + this.displayEl = this.wrap.createChild({ + tag: 'div', + style: 'vertical-align:top;', + html: '' + }); + + this.displayEl.setWidth(this.width - this.labelWidth); + this.displayEl.setHeight(this.getHeight()); + + this.updateDisplayEl(); + }, + + showTextArea: function(){ + if (!this.rendered){ + return; + } + + if (this.displayEl){ + this.displayEl.remove(); + delete this.displayEl; + } + + if (this.linkEl){ + this.linkEl.update('Copy Latest CEG_Plan'); + } + + if (this.inputEl) + this.inputEl.setVisible(true); + }, + + updateDisplayEl: function(){ + if (!this.displayEl){ + return; + } + + var rec = EHR.DataEntryUtils.getBoundRecord(this); + if (rec && rec.get('Id')){ + this.getMostRecentCEG_Plan(rec, function(ret, Id){ + if (!ret || !this.displayEl){ + return; + } + + if (ret.mostRecentCeg_Plan && ret.isActive){ + this.displayEl.update(ret.mostRecentCeg_Plan); + } + else { + this.displayEl.update('Either no active case or no CEG_Plan for ' + (Id || rec.get('Id'))); + } + }); + } + else { + this.displayEl.update('No animal entered'); + } + }, + + copyMostRecentCEG_Plan: function(){ + var rec = EHR.DataEntryUtils.getBoundRecord(this); + if (!rec || !rec.get('Id')){ + Ext4.Msg.alert('Error', 'No Id Entered'); + return; + } + + Ext4.Msg.wait('Loading...'); + this.showTextArea(); + + this.getMostRecentCEG_Plan(rec, function(ret){ + Ext4.Msg.hide(); + + if (ret){ + this.setValue(ret.mostRecentCeg_Plan); + this.linkEl.update('Refresh CEG Plan'); + } + }, true); + }, + + getMostRecentCEG_Plan: function(rec, cb, alwaysUseCallback){ + var date = rec.get('date') || new Date(); + var id = rec.get('Id'); + this.pendingIdRequest = id; + + LABKEY.Query.executeSql({ + schemaName: 'study', + sql: 'SELECT c.Id, c.CEG_Plan as mostRecentCeg_Plan, c.caseid, c.caseid.category as caseCategory, c.caseid.isActive as isActive FROM study.clinRemarks c WHERE (c.category != \'Replaced SOAP\' OR c.category IS NULL) AND c.CEG_Plan IS NOT NULL AND c.Id = \'' + rec.get('Id') + '\' ORDER BY c.date DESC LIMIT 1', + failure: LDK.Utils.getErrorCallback(), + scope: this, + success: function(results){ + if (!alwaysUseCallback && id != this.pendingIdRequest){ + console.log('more recent request, aborting'); + return; + } + + if (results && results.rows && results.rows.length && results.rows[0].mostRecentCeg_Plan){ + cb.call(this, results.rows[0], results.rows[0].Id); + } + else { + cb.call(this, null, id); + } + } + }); + }, + + onDestroy : function(){ + if (this.linkEl){ + this.linkEl.removeAllListeners(); + this.linkEl.remove(); + } + + if (this.linkDiv){ + this.linkDiv.removeAllListeners(); + this.linkDiv.remove(); + } + + if (this.displayEl){ + //NOTE: no listeners were added + //this.displayEl.removeAllListeners(); + this.displayEl.remove(); + } + + if (this.wrap){ + this.wrap.remove(); + } + + this.callParent(this); + }, + + setValue: function(){ + this.callParent(arguments); + + if (this.getValue()){ + this.showTextArea(); + } + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ASB_Services.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ASB_Services.js index 284227561..be9f4ab82 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/ASB_Services.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ASB_Services.js @@ -1,3 +1,4 @@ + /* * Copyright (c) 2013-2014 LabKey Corporation * @@ -12,12 +13,38 @@ EHR.model.DataModelManager.registerMetadata('ASB_Services', { chargetype: { defaultValue: 'DCM: ASB Services', hidden: true - } - }, + }, + date: { + xtype: 'xdatetime', + extFormat: 'Y-m-d H:i', + defaultValue: (new Date()).format('Y-m-d 8:0') + }, + type: { + defaultValue: 'Procedure', + hidden: true + }, + procedureid: { + lookup: { + filterArray: [ + + LABKEY.Filter.create('category', 'Research', LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('active', true, LABKEY.Filter.Types.EQUAL) + ] + }}}, 'study.blood': { chargetype: { defaultValue: 'DCM: ASB Services', hidden: true + }, + performedby: { + //defaultValue: LABKEY.Security.currentUser.displayName, + hidden: false, + header: 'Completed by' + }, + date: { + xtype: 'xdatetime', + extFormat: 'Y-m-d H:i', + defaultValue: (new Date()).format('Y-m-d 8:0') } }, 'study.drug': { @@ -25,11 +52,73 @@ EHR.model.DataModelManager.registerMetadata('ASB_Services', { defaultValue: 'DCM: ASB Services', hidden: true }, + date: { + xtype: 'xdatetime', + extFormat: 'Y-m-d H:i', + defaultValue: (new Date()).format('Y-m-d 8:0') + }, + Billable: { + defaultValue: 'Yes', + hidden: false + }, + category: { + defaultValue: 'Research', + hidden: true + }, + remark: { + header: 'Special Instructions', + hidden: false + }, + reason: { + defaultValue: 'Research', + hidden: false + }, + lot: { + hidden: true + }, code: { editorConfig: { - defaultSubset: 'Drugs and Procedures' - } + defaultSubset: 'Research' + }, + header: 'Agent Administered' } + }, + 'ehr.requests': { + remark: { + label: 'Lab Phone # ', + width: 300, + height: 20, + hidden: false + } + } + // Modified: 7-27-2017 R.Blasa not needed for this version + //'study.treatment_order': { + // chargetype: { + // defaultValue: 'DCM: ASB Services', + // hidden: true + // }, + // date: { + // defaultValue: new Date() + // }, + // Billable: { + // defaultValue: 'Yes', + // hidden: true + // }, + // code: { + // header: 'Agent', + // editorConfig: { + // defaultSubset: 'Research' + // } + // }, + // category: { + // defaultValue: 'Research', + // hidden: true + // }, + // remark: { + // header: 'Special Instructions', + // hidden: false + // } + //} } }); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Biopsy_Staff.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/Biopsy_Staff.js new file mode 100644 index 000000000..42b8f28ca --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Biopsy_Staff.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created: 10-12-2017 R.Blasa +EHR.model.DataModelManager.registerMetadata('Biopsy_Staff', { + + byQuery: { + + 'ehr.encounter_participants': { + Id: { + hidden: false, + allowBlank: false + }, + userid: { + hidden: true, + columnConfig: { + width: 200 + } + }, + username: { + hidden: false, + allowBlank: false, + columnConfig: { + width: 200 + }, + lookup: { + xtype: 'labkey-combo', + schemaName: 'onprc_ehr', + queryName: 'Reference_StaffNames', + keyColumn: 'username', + displayColumn: 'username', + filterArray: [ + LABKEY.Filter.create('DisableDate', null, LABKEY.Filter.Types.ISBLANK), + LABKEY.Filter.create('Type', 'Necropsy', LABKEY.Filter.Types.EQUAL)], + columns: 'username,FirstName,LastName,Type,DisableDate', + sort: 'username' + + }, + editorConfig: { + anyMatch: true, + listConfig: { + innerTpl: '{[values.username + (values.username ? " (" + values.LastName + (values.FirstName ? ", " + values.FirstName : "") + ")" : "")]}', + getInnerTpl: function(){ + return this.innerTpl; + } + } + } + }, + role: { + allowBlank: false, + columnConfig: { + width: 200 + } + }, + comment: { + hidden: true + } + } + + + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalReport.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalReport.js new file mode 100644 index 000000000..c9618b8c1 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalReport.js @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +EHR.model.DataModelManager.registerMetadata('ClinicalReport_ONPRC', { + allQueries: { + date: { + getInitialValue: function(v, rec){ + if (v){ + return v; + } + else if (rec && rec.storeCollection && rec.storeCollection.getRemarksRec){ + var rr = rec.storeCollection.getRemarksRec(); + if (rr && rr.get('date')){ + return rr.get('date'); + } + } + + return new Date(); + } + } + }, + byQuery: { + 'study.clinremarks': { + project: { + hidden: false, + allowBlank: false + }, + hx: { + hidden: false + }, + p2: { + formEditorConfig: { + xtype: 'ehr-plantextarea' + }, + height: 75 + }, + CEG_Plan: { + formEditorConfig: { + xtype: 'onprc_ehr-CEG_Plantextarea' + }, + height: 52 + } + }, + 'study.treatment_order': { + date: { + getInitialValue: function(v, rec){ + if (v) + return v; + + var ret = Ext4.Date.clearTime(new Date()); + ret = Ext4.Date.add(ret, Ext4.Date.DAY, 1); + ret.setHours(8); + return ret; + } + } + } + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalRounds.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalRounds.js new file mode 100644 index 000000000..09bec1e6e --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalRounds.js @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created: 10-10-2017 R.Blasa + +EHR.model.DataModelManager.registerMetadata('ClinicalRounds_ONPRC', { + allQueries: { + + }, + byQuery: { + 'study.clinremarks': { + Id: { + editable: false, + columnConfig: { + editable: false + } + }, + category: { + defaultValue: 'Clinical', + hidden: true + }, + hx: { + hidden: false + }, + s: { + hidden: true + }, + o: { + hidden: true + }, + a: { + hidden: true + }, + p: { + hidden: true + }, + CEG_Plan: { + + height: 22 + }, + remark: { + hidden: false + } + }, + 'study.blood': { + reason: { + defaultValue: 'Clinical' + }, + instructions: { + hidden: true + } + }, + 'study.encounters': { + instructions: { + hidden: true + } + }, + 'study.clinical_observations': { + Id: { + editable: false, + columnConfig: { + editable: false + } + } + } + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css b/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css new file mode 100644 index 000000000..cbb102d3d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css @@ -0,0 +1,4 @@ + +.x4-form-item, +.x4-form-field { + font: normal 14px "Arial", Arial, Helvetica, sans-serif; } \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/NHPTrainingProperties.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/NHPTrainingProperties.js index 9b50fa90c..5de5cceb3 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/NHPTrainingProperties.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/NHPTrainingProperties.js @@ -15,29 +15,34 @@ EHR.model.DataModelManager.registerMetadata('NHPTraining', { byQuery: { 'onprc_ehr.NHP_Training': { training_Start_Date: { - xtype: 'xdatetime', - editorConfig: { - dateFormat: 'Y-m-d', - timeFormat: 'H:i' - }, - + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, columnConfig: { width: 150 } }, training_End_Date: { - xtype: 'xdatetime', - editorConfig: { - dateFormat: 'Y-m-d', - timeFormat: 'H:i' - }, - + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, columnConfig: { width: 150 } }, + //Added: 5-22-2018 R.Blasa + created: { + hidden: true, + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat + }, + //Added: 5-22-2018 R.Blasa + modified: { + hidden: true, + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat + }, + training_type: { allowBlank: false, xtype: 'onprc_TrainingType' , diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Pairing_Properties.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/Pairing_Properties.js index 9852839e0..b4fc651e5 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/Pairing_Properties.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Pairing_Properties.js @@ -15,40 +15,40 @@ EHR.model.DataModelManager.registerMetadata('Pairing_Properties', { outcome: { allowBlank: false, - lookup: { filterArray: [ LABKEY.Filter.create('date_disabled', null, LABKEY.Filter.Types.ISBLANK) ] } + }, - } , - - eventType: { + eventtype: { allowBlank: false, - lookup: { - filterArray: [ - LABKEY.Filter.create('date_disabled', null, LABKEY.Filter.Types.ISBLANK) - ] + sort: 'sort_order' } - - }, - goal: { allowBlank: false, - lookup: { filterArray: [ - LABKEY.Filter.create('dated_disabled', null, LABKEY.Filter.Types.ISBLANK) + LABKEY.Filter.create('date_disabled', null, LABKEY.Filter.Types.ISBLANK) ] } + }, + endeventType: { + lookup: { + sort: 'sort_order' + } + }, + enddate: { + hidden: false }, + separationreason: { - allowBlank: false, + allowBlank: true, lookup: { filterArray: [ @@ -56,9 +56,9 @@ EHR.model.DataModelManager.registerMetadata('Pairing_Properties', { ] } - }, observation: { + allowBlank: true, columnConfig: { width: 200 }, @@ -68,8 +68,18 @@ EHR.model.DataModelManager.registerMetadata('Pairing_Properties', { ] } + }, + + remark2: { + xtype: 'textareafield', + width: 400, + + }, + remark: { + width: 400 + }, + } - } } }); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Parentage_Properties.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/Parentage_Properties.js new file mode 100644 index 000000000..3c92b0548 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Parentage_Properties.js @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created 12-26-2017 R.Blasa +EHR.model.DataModelManager.registerMetadata('ParentageProperty', { + allQueries: { + + }, + byQuery: { + + 'study.parentage': { + + date: { + xtype: 'datefield', + extFormat: LABKEY.extDefaultDateFormat, + columnConfig: { + width: 100 + } + } + } + + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/PathologyTissues.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/PathologyTissues.js new file mode 100644 index 000000000..fc671ff3b --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/PathologyTissues.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +//Created: 5-5-2017 R.Blasa +EHR.model.DataModelManager.registerMetadata('PathTissues', { + allQueries: { + }, + byQuery: { + 'study.encounters': { + type: { + defaultValue: 'Tissues', + hidden: true + }, + enddate: { + hidden: true + }, + project: { + header: 'Center Project' + }, + + + chargetype: { + hidden: true + }, + procedureid: { + defaultValue: 1082, + hidden: true + }, + + caseno: { + hidden: true + }, + remark: { + hidden: true + } + } + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Pathology_Notes.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/Pathology_Notes.js index a38f8ef10..33f9df103 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/Pathology_Notes.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Pathology_Notes.js @@ -30,6 +30,57 @@ EHR.model.DataModelManager.registerMetadata('Necropsy_Notes', { } } }, + //Added: 10-12-2017 R.Blasa + 'ehr.encounter_participants': { + Id: { + hidden: false, + allowBlank: false + }, + userid: { + hidden: true, + columnConfig: { + width: 200 + } + }, + username: { + hidden: false, + allowBlank: false, + columnConfig: { + width: 200 + }, + lookup: { + xtype: 'labkey-combo', + schemaName: 'onprc_ehr', + queryName: 'Reference_StaffNames', + keyColumn: 'username', + displayColumn: 'username', + filterArray: [ + LABKEY.Filter.create('DisableDate', null, LABKEY.Filter.Types.ISBLANK), + LABKEY.Filter.create('Type', 'Necropsy', LABKEY.Filter.Types.EQUAL)], + columns: 'username,FirstName,LastName,Type,DisableDate', + sort: 'username' + + }, + editorConfig: { + anyMatch: true, + listConfig: { + innerTpl: '{[values.username + (values.username ? " (" + values.LastName + (values.FirstName ? ", " + values.FirstName : "") + ")" : "")]}', + getInnerTpl: function(){ + return this.innerTpl; + } + } + } + }, + role: { + allowBlank: false, + columnConfig: { + width: 200 + } + }, + comment: { + hidden: true + } + }, 'onprc_ehr.encounter_summaries_remarks': { Id: { hidden: true diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ProjectAnimalConditions.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ProjectAnimalConditions.js index de1eb59fa..7a7ed5a7d 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/ProjectAnimalConditions.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ProjectAnimalConditions.js @@ -15,34 +15,23 @@ EHR.model.DataModelManager.registerMetadata('ProjectAnimalConditions', { assignCondition: { allowBlank: false, - - columnConfig: { - width: 200 - }, lookup: { filterArray: [ LABKEY.Filter.create('datedisabled', null, LABKEY.Filter.Types.ISBLANK) ] } - } , + } , projectedReleaseCondition: { allowBlank: false, - columnConfig: { - width: 20 - }, lookup: { filterArray: [ LABKEY.Filter.create('datedisabled', null, LABKEY.Filter.Types.ISBLANK) ] } - }, - releaseCondition: { - columnConfig: { - width: 200 - }, + lookup: { filterArray: [ LABKEY.Filter.create('datedisabled', null, LABKEY.Filter.Types.ISBLANK) @@ -50,7 +39,6 @@ EHR.model.DataModelManager.registerMetadata('ProjectAnimalConditions', { } } - } } }); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js new file mode 100644 index 000000000..875c965a9 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js @@ -0,0 +1,92 @@ + +//Created: 1-16-2018 R.Blasa + +EHR.model.DataModelManager.registerMetadata('ResearchProcedures', { + allQueries: { + performedby: { + allowBlank: true + } + }, + byQuery: { + 'study.encounters': { + instructions: { + header: 'Special Instructions', + hidden: false + }, + chargetype: { + defaultValue: 'Research Staff', + allowBlank: false + }, + performedby: { + defaultValue: LABKEY.Security.currentUser.displayName + }, + type: { + defaultValue: 'Procedure', + hidden: true + }, + title: { + hidden: true + }, + caseno: { + hidden: true + }, + remark: { + columnConfig: { + width: 400 + } + }, + procedureid: { + lookup: { + filterArray: [ + LABKEY.Filter.create('category', 'Surgery', LABKEY.Filter.Types.NEQ), + LABKEY.Filter.create('active', true, LABKEY.Filter.Types.EQUAL) + ] + } + } + }, + 'study.blood': { + chargetype: { + defaultValue: 'Research Staff', + allowBlank: false + }, + instructions: { + hidden: true + }, + reason: { + defaultValue: 'Research' + } + }, + 'study.drug': { + category: { + defaultValue: 'Research', + editable: false + }, + project: { + allowBlank: false + }, + code: { + editorConfig: { + xtype: 'ehr-snomedcombo', + defaultSubset: 'Drugs and Procedures' + } + }, + chargetype: { + defaultValue: 'Research Staff', + allowBlank: false + } + }, + 'study.treatment_order': { + category: { + defaultValue: 'Research', + editable: false + }, + code: { + editorConfig: { + xtype: 'ehr-snomedcombo', + defaultSubset: 'Drugs and Procedures' + } + } + } + } +}); + diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js new file mode 100644 index 000000000..e382e92f8 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js @@ -0,0 +1,25 @@ + +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +EHR.model.DataModelManager.registerMetadata('Surgery_Blood', { + allQueries: { + + }, + byQuery: { + + 'study.blood': { + + date: { + getInitialValue: function(v){ + return v; + } + } + + } + + + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Surgery_Staff.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/Surgery_Staff.js new file mode 100644 index 000000000..a344d8590 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Surgery_Staff.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created: 7-23-2018 R.Blasa +EHR.model.DataModelManager.registerMetadata('Biopsy_Staff', { + + byQuery: { + + 'ehr.encounter_participants': { + Id: { + hidden: false, + allowBlank: false + }, + userid: { + hidden: true, + columnConfig: { + width: 200 + } + }, + username: { + hidden: false, + allowBlank: false, + columnConfig: { + width: 200 + }, + lookup: { + xtype: 'labkey-combo', + schemaName: 'onprc_ehr', + queryName: 'Reference_StaffNames', + keyColumn: 'username', + displayColumn: 'username', + filterArray: [ + LABKEY.Filter.create('DisableDate', null, LABKEY.Filter.Types.ISBLANK), + LABKEY.Filter.create('Type', 'Surgery', LABKEY.Filter.Types.EQUAL)], + columns: 'username,FirstName,LastName,Type,DisableDate,displayname', + sort: 'username' + }, + editorConfig: { + anyMatch: true, + listConfig: { + innerTpl: '{[values.username + (values.username ? " (" + values.LastName + (values.FirstName ? ", " + values.FirstName : "") + ")" : "")]}', + getInnerTpl: function(){ + return this.innerTpl; + } + } + } + }, + role: { + allowBlank: false, + columnConfig: { + width: 200 + } + }, + comment: { + hidden: true + } + } + + + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/onprcOverrides.js b/onprc_ehr/resources/web/onprc_ehr/onprcOverrides.js new file mode 100644 index 000000000..a6f35263e --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/onprcOverrides.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +Ext4.namespace('ONPRC_EHR'); + +/** Override to never sort the IDs */ +LDK.Utils.splitIds = function(subjects, unsorted) { + subjects = Ext4.String.trim(subjects); + subjects = subjects.replace(/[\s,;]+/g, ';'); + subjects = subjects.replace(/(^;|;$)/g, ''); + subjects = subjects.toLowerCase(); + + if (subjects){ + subjects = subjects.split(';'); + } + else { + subjects = []; + } + + return Ext4.unique(subjects); +}; diff --git a/onprc_ehr/resources/web/onprc_ehr/onprcReports.js b/onprc_ehr/resources/web/onprc_ehr/onprcReports.js index d0b571d32..ab1a6a16e 100644 --- a/onprc_ehr/resources/web/onprc_ehr/onprcReports.js +++ b/onprc_ehr/resources/web/onprc_ehr/onprcReports.js @@ -193,6 +193,8 @@ EHR.reports.currentBlood = function(panel, tab){ if (subjects.length < 2) { for (var i = 0; i < subjects.length; i++) + + { var str = subjects[i]; var filterArray = panel.getFilterArray(tab); @@ -245,10 +247,10 @@ EHR.reports.currentBlood = function(panel, tab){ title: 'Overview' + title, schemaName: 'study', queryName: 'demographicsBloodSummary',//'demographicsBloodSummary', - // viewName: 'NewBloodCalc', - filterArray: filterArray.removable.concat(filterArray.nonRemovable) - } - }); + // viewName: 'NewBloodCalc', + filterArray: filterArray.removable.concat(filterArray.nonRemovable) + } + }); } if (toAdd.length) @@ -347,11 +349,11 @@ EHR.reports.potentialParents = function(panel, tab){ style: 'padding-bottom: 20px;', bodyStyle: 'padding: 5px;', html: 'This report calculates potential parents for the selected animal(s). The potential parents are determined as follows:' + - '

' + - '
    ' + - '
  • Potential dams are determined by finding any female housed in the animal\'s birth location at the time of birth, which were at least 2.5 years old at the time. Note: this report considers housing in whole-day increments in order to avoid missing potential parents due to errors in the timestamp of transfers.
  • ' + - '
  • Potential sires are determined by finding the locations where all potential dams were housed during the conception window (defined below) relative to the animal\'s birth. The potential sires are any male animals housed in these locations during the conception window, which are at least 2.5 years old at the time.
  • ' + - '
' + '

' + + '
    ' + + '
  • Potential dams are determined by finding any female housed in the animal\'s birth location at the time of birth, which were at least 2.5 years old at the time. Note: this report considers housing in whole-day increments in order to avoid missing potential parents due to errors in the timestamp of transfers.
  • ' + + '
  • Potential sires are determined by finding the locations where all potential dams were housed during the conception window (defined below) relative to the animal\'s birth. The potential sires are any male animals housed in these locations during the conception window, which are at least 2.5 years old at the time.
  • ' + + '
' }); tab.add({ @@ -373,8 +375,8 @@ EHR.reports.potentialParents = function(panel, tab){ border: false }, items: [{ - html: 'Choose Conception Range (Days Prior To Birth):', - style: 'padding-bottom: 10px;' + html: 'Choose Conception Range (Days Prior To Birth):', + style: 'padding-bottom: 10px;' },{ xtype: 'numberfield', hideTrigger: true, @@ -761,12 +763,12 @@ EHR.reports.onprcSnapshot = function(panel, tab){ var idcolor = false; if (str.substr(0,2)== 'gp' || str.substr(0,3)== 'rbr') { - idcolor = true; + idcolor = true; } toAdd.push({ xtype: 'ldk-webpartpanel', //title: 'Overview: ' + subjects[i], //Added 4-12-2016 Blasa - // title: 'Overview: ' + '' + subjects[i]+ '', + // title: 'Overview: ' + '' + subjects[i]+ '', //Added 4-12-2016 Blasa title: idcolor?'Overview: ' + '' + subjects[i]+ '':'Overview: ' + subjects[i], @@ -970,4 +972,108 @@ EHR.reports.surgeryCasesClosedToday = function(panel, tab){ removeableFilters: filterArray.removable }) }); -}; \ No newline at end of file +} + +//Modified 4-1-2016 R.Blasa +EHR.reports.onprcweightGraph = function(panel, tab){ + if (tab.filters.subjects){ + renderSubjects(tab.filters.subjects, tab); + } + else + { + panel.resolveSubjectsFromHousing(tab, renderSubjects, this); + } + + function renderSubjects(subjects, tab) + { + if (!subjects.length) + { + tab.add({ + html: 'No animals were found.', + border: false + }); + + return; + } + + var toAdd = []; + + toAdd.push({ + html: 'Note: Please click the animal ID to open the graphical representation of the same report. Choose a different tab, to display the animal\'s weight record in more detail.', + style: 'padding-bottom: 20px;', + border: false + }); + var filterArray = panel.getFilterArray(tab); + var title = panel.getTitleSuffix(); + toAdd.push({ + xtype: 'ldk-querypanel', + style: 'margin-bottom:20px;', + queryConfig: { + title: 'Weights' , + schemaName: 'study', + queryName: 'demographics', + viewName: 'Snapshot', + filterArray: filterArray.removable.concat(filterArray.nonRemovable) + } + }); + + if (toAdd.length) + tab.add(toAdd); + + } +}; + +EHR.reports.kinshipSummary = function(panel, tab){ + var filterArray = panel.getFilterArray(tab); + var title = panel.getTitleSuffix(); + var ids = panel.getFilterContext().subjects; + + tab.add({ + xtype: 'panel', + border: false, + subjectList: ids, + bodyStyle: 'padding: 5px;', + defaults: { + border: false + }, + items: [{ + xtype: 'ldk-linkbutton', + hidden: !ids || !ids.length, + text: 'Click Here To Limit To Animals In Selection', + linkTarget: '_blank', + linkCls: 'labkey-text-link', + style: 'margin-bottom: 20px;', + handler: function(btn){ + var p = btn.up('panel'); + if (p.subjectList) { + var qwp = p.down('ldk-querypanel').qwp; + if (qwp) { + qwp.removeableFilters = qwp.removeableFilters || []; + qwp.removeableFilters.push(LABKEY.Filter.create('Id2', p.subjectList.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); + + var dr = LABKEY.DataRegions[qwp.dataRegionName]; + if (dr){ + dr.addFilter(LABKEY.Filter.create('Id2', p.subjectList.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); + dr.refresh(); + } + } + } + } + },{ + xtype: 'container', + border: false, + items: [{ + xtype: 'ldk-querypanel', + style: 'margin-bottom:20px;', + queryConfig: panel.getQWPConfig({ + schemaName: 'ehr', + queryName: 'kinshipSummary', + title: 'Kinship' + title, + filters: filterArray.nonRemovable, + removeableFilters: filterArray.removable || [] + }) + }] + }] + }); + +} \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/AddScheduledTreatmentPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/AddScheduledTreatmentPanel.js index 2df5758fc..08663bc16 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/AddScheduledTreatmentPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/AddScheduledTreatmentPanel.js @@ -58,6 +58,7 @@ Ext4.define('onprc_ehr.panel.AddScheduledTreatmentPanel', { data: [ ['800', '8:00 AM'], ['1200', '12:00 Noon'], + ['1400', '2:00 PM'], ['1600', '4:00 PM'], ['2000', '8:00 PM'] ] diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsCasePanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsCasePanel.js index 4d17e285c..d0b42a561 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsCasePanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsCasePanel.js @@ -169,7 +169,7 @@ Ext4.define('onprc_ehr.panel.AnimalDetailsCasePanel', { hidden: EHR.Security.hasClinicalEntryPermission() && !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'update', [{schemaName: 'study', queryName: 'Treatment Orders'}]), handler: function(){ if (this.subjectId){ - Ext4.create('EHR.window.ManageTreatmentsWindow', {animalId: this.subjectId}).show(); + Ext4.create('onprc_ehr.window.ManageTreatmentsWindow', {animalId: this.subjectId}).show(); } else { console.log('no id'); diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/BloodSummaryPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/BloodSummaryPanel.js index 7b841e406..a200dcc60 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/BloodSummaryPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/BloodSummaryPanel.js @@ -18,9 +18,9 @@ Ext4.define('ONPRC.panel.BloodSummaryPanel', { defaults: { border: false }, - items: [{ + /* items: [{ html: 'Loading...' - }] + }]*/ }); this.callParent(); @@ -37,7 +37,7 @@ Ext4.define('ONPRC.panel.BloodSummaryPanel', { // viewName: 'newBloodCalc', filterArray: [LABKEY.Filter.create('id', this.subjects.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)], // columns: 'id,species,species/blood_per_kg,species/max_draw_pct,species/blood_draw_interval,id/MostRecentWeight/mostRecentWeight,id/MostRecentWeight/mostRecentWeightDate,Id/demographics/calculated_status', - columns: 'id,Species,Gender,MostRecentBCS,BCSDate,mostRecentWeight,mostRecentWeightDate,blood_draw_interval,bloodPrevious,bloodFuture,blood_per_kg,FixedRateCalculation,TotalBloodVolume,AllowableBlood,AvailableBlood,Method,Id/demographics/calculated_status', + columns: 'id,Species,species/blood_per_kg,species/max_draw_pct,species/blood_draw_interval,Gender,MostRecentBCS,BCSDate,weight,MostRecentWeightDate,blood_draw_interval,bloodPrevious,bloodFuture,blood_per_kg,FixedRateCalculation,TotalBloodVolume,AllowableBlood,AvailableBlood,Method,Id/demographics/calculated_status', requiredVersion: 9.1, sort: 'id', @@ -128,7 +128,7 @@ Ext4.define('ONPRC.panel.BloodSummaryPanel', { }); if (!bds || !bds.length) { - var maxDraw = dd.getValue('species/blood_per_kg') * dd.getValue('species/max_draw_pct') * dd.getValue('id/MostRecentWeight/mostRecentWeight'); + var maxDraw = dd.getValue('totalAllowable'); cfg.items.push({ html: 'There are no previous or future blood draws with the relevant timeframe. The maximum amount of ' + Ext4.util.Format.round(maxDraw, 2) + ' mL can be drawn.', border: false @@ -164,6 +164,8 @@ Ext4.define('ONPRC.panel.BloodSummaryPanel', { }; //this assumes we sorted on date + + var newRows = []; var rowPrevious; var seriesIds = []; @@ -207,15 +209,57 @@ Ext4.define('ONPRC.panel.BloodSummaryPanel', { if (currentRow){ toAdd.push({ - html: 'The amount of blood available if drawn today is: ' + Ext4.util.Format.round(currentRow.allowableDisplay.value, 1) + ' mL. The graph below shows how the amount of blood available will change over time, including when previous draws will drop off.
', + html: 'The amount of blood available if drawn today is: ' + Ext4.util.Format.round(currentRow.allowableDisplay.value, 1) + ' mL.
', border: false, style: 'margin-bottom: 20px' }); } + toAdd.push({ + html: '', + border: false, + style: 'margin-bottom: 10px;' + }); + + toAdd.push({ + xtype: 'ldk-querypanel', + style: 'margin-bottom: 10px;', + queryConfig: LDK.Utils.getReadOnlyQWPConfig({ + title: 'Recent/Scheduled Blood Draws: ' + subject, + schemaName: 'study', + queryName: 'bloodDrawsByDay', + allowHeaderLock: false, + //frame: 'none', + filters: [ + LABKEY.Filter.create('Id', subject, LABKEY.Filter.Types.EQUAL), + //THis filter is looking to identify values from bloodDraws by Day and attempts to get the species value, it makes better sense to only filter for the animal + //ID and do the other calcs in the actual query + LABKEY.Filter.create('date', '-' + (dd.getValue('species/blood_draw_interval') * 2 ) + 'd', LABKEY.Filter.Types.DATE_GREATER_THAN_OR_EQUAL) + ] + + }) + }); + + toAdd.push({ + xtype: 'ldk-querypanel', + style: 'margin-bottom: 10px;', + queryConfig: LDK.Utils.getReadOnlyQWPConfig({ + title: 'Pending/Not-Yet-Approved Blood Draws: ' + subject, + schemaName: 'study', + queryName: 'blood', + allowHeaderLock: false, + //frame: 'none', + filters: [ + LABKEY.Filter.create('Id', subject, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('qcState','Completed' , LABKEY.Filter.Types.NOT_EQUAL) + ], + sort: '-date' + }) + }); +/*toAdd.push({ xtype: 'container', - //title: 'Available Blood: ' + subject, + title: 'Available Blood: ' + subject, items: [{ xtype: 'ldk-graphpanel', margin: '0 0 0 0', @@ -293,47 +337,7 @@ Ext4.define('ONPRC.panel.BloodSummaryPanel', { }, this); } }] - }); - - toAdd.push({ - html: '', - border: false, - style: 'margin-bottom: 10px;' - }); - - toAdd.push({ - xtype: 'ldk-querypanel', - style: 'margin-bottom: 10px;', - queryConfig: LDK.Utils.getReadOnlyQWPConfig({ - title: 'Recent/Scheduled Blood Draws: ' + subject, - schemaName: 'study', - queryName: 'bloodDrawsByDay', - allowHeaderLock: false, - //frame: 'none', - filters: [ - LABKEY.Filter.create('Id', subject, LABKEY.Filter.Types.EQUAL), - LABKEY.Filter.create('date', '-' + (dd.getValue('species/blood_draw_interval') * 2) + 'd', LABKEY.Filter.Types.DATE_GREATER_THAN_OR_EQUAL) - ], - sort: '-date' - }) - }); - - toAdd.push({ - xtype: 'ldk-querypanel', - style: 'margin-bottom: 10px;', - queryConfig: LDK.Utils.getReadOnlyQWPConfig({ - title: 'Pending/Not-Yet-Approved Blood Draws: ' + subject, - schemaName: 'study', - queryName: 'blood', - allowHeaderLock: false, - //frame: 'none', - filters: [ - LABKEY.Filter.create('Id', subject, LABKEY.Filter.Types.EQUAL), - LABKEY.Filter.create('countsAgainstVolume', false, LABKEY.Filter.Types.EQUAL) - ], - sort: '-date' - }) - }); + });*/ toAdd.push({ html: '', diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js new file mode 100644 index 000000000..3836ef78d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js @@ -0,0 +1,519 @@ + +//Created: 12-13-2016 R.Blasa +//Modified: 7-17-2017 R.Blasa + +Ext4.define('onprc_ehr.panel.EnterDataPanel', { + extend: 'LDK.panel.QueryTabPanel', + + initComponent: function(){ + Ext4.apply(this, { + items: this.getItems(), + minHeight: 200 + }); + + this.loadData(); + + this.callParent(); + }, + + loadData: function(){ + EHR.Utils.getDataEntryItems({ + includeFormElements: false, + scope: this, + success: this.onLoad + }); + }, + + onLoad: function(results){ + var formMap = {}; + Ext4.each(results.forms, function(form){ + if (form.isAvailable && form.isVisible && form.canInsert){ + formMap[form.category] = formMap[form.category] || []; + formMap[form.category].push({ + name: form.label, + url: LABKEY.ActionURL.buildURL('ehr', 'dataEntryForm', null, {formType: form.name}) + }); + } + }, this); + + var sectionNames = Ext4.Object.getKeys(formMap); + sectionNames = sectionNames.sort(); + + var sections = []; + Ext4.Array.forEach(sectionNames, function(section){ + var items = formMap[section]; + items = LDK.Utils.sortByProperty(items, 'name', false); + sections.push({ + header: section, + items: items + }); + }, this); + + var tab = this.down('#enterNew'); + tab.removeAll(); + tab.add({ + xtype: 'ldk-navpanel', + sections: sections + }); + }, + + getItems: function(){ + return [ + { + xtype: 'panel', + bodyStyle: 'margin: 5px;', + title: 'Enter New Data', + itemId: 'enterNew', + defaults: { + border: false + }, + items: [{ + html: 'Loading...' + }] + }, + { + xtype: 'ldk-querypanel', + bodyStyle: 'margin: 5px;', + title: 'My Tasks', + queryConfig: { + schemaName: 'onprc_ehr', //Modified: 3-27-2017 R.Blasa + queryName: 'my_tasks', + viewName: 'Active Tasks' + } + },{ + xtype: 'ldk-querypanel', + bodyStyle: 'margin: 5px;', + title: 'All Tasks', + queryConfig: { + schemaName: 'ehr', + queryName: 'tasks', + viewName: 'Active Tasks' + } + },{ + title: 'Queues', + bodyStyle: 'margin: 5px;', + items: [{ + xtype: 'ldk-navpanel', + sections: [{ + header: 'Reports', + renderer: function (item) { + return item; + }, + items: [{ + xtype: 'ldk-linkbutton', + text: 'Service Request Summary', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('ldk', 'runNotification', null, {key: 'org.labkey.onprc_ehr.notification.RequestAdminNotification'}) + }] + },{ + //header: 'Blood Draw Requests', + header: 'ASB Service Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Blood Draws', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Blood Draws', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Scheduled Today', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Blood Draws', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + }] + } + }, + items: [{ + name: 'Blood Draw Request', //Modified: 1-7-2017 R.Blasa restored back as ASB Services + chargeType: 'DCM: ASB Services' +// },{ +// name: 'Clinical Services', +// chargeType: 'DCM: Clinical Services' +// },{ +// name: 'Colony Services', +// chargeType: 'DCM: Colony Services' +// },{ +// name: 'Surgery Services', +// chargeType: 'DCM: Surgery' + }] + },{ + //Modified: 7-27-2017 R.Blasa Removed + ////header: 'Treatment Requests', + //renderer: function(item){ + // return { + // layout: 'hbox', + // bodyStyle: 'padding: 2px;background-color: transparent;', + // defaults: { + // border: false + // }, + // items: [{ + // html: item.name + ':', + // width: 200 + // },{ + // xtype: 'ldk-linkbutton', + // text: 'Unapproved Requests', + // linkCls: 'labkey-text-link', + // href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Treatment Orders', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + // },{ + // xtype: 'ldk-linkbutton', + // text: 'Approved Requests', + // linkCls: 'labkey-text-link', + // style: 'padding-left: 5px;', + // href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Treatment Orders', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + // },{ + // xtype: 'ldk-linkbutton', + // text: 'Scheduled Today', + // linkCls: 'labkey-text-link', + // style: 'padding-left: 5px;', + // href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Treatment Orders', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + // }] + // } + //}, + //items: [{ + // //name: 'ASB Services', + // name: 'Treatment Orders Request', + // chargeType: 'DCM: ASB Services' + // + //}] + //},{ + //header: 'Treatment Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Drug Administration', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Drug Administration', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Scheduled Today', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Drug Administration', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + }] + } + }, + items: [{ + //name: 'ASB Services', + name: 'Treatment Given Request', + chargeType: 'DCM: ASB Services' + + }] + },{ + //header: 'Procedure Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'encounters', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'encounters', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Scheduled Today', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'encounters', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + }] + } + }, + items: [{ + //name: 'ASB Services', + name: 'Procedure Request', + chargeType: 'DCM: ASB Services' + + }] + },{ + //header: 'Blood Draw Requests', + header: 'Colony Service Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Blood Draws', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Blood Draws', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Scheduled Today', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Blood Draws', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + }] + } + }, + items: [{ + name: 'Blood Draw Request', //Modified: 1-7-2017 R.Blasa restored back as ASB Services + chargeType: 'DCM: Colony Services' + + }] + },{ + //Modified: 7-27-2017 R.Blasa not needed + ////header: 'Treatment Requests', + //renderer: function(item){ + // return { + // layout: 'hbox', + // bodyStyle: 'padding: 2px;background-color: transparent;', + // defaults: { + // border: false + // }, + // items: [{ + // html: item.name + ':', + // width: 200 + // },{ + // xtype: 'ldk-linkbutton', + // text: 'Unapproved Requests', + // linkCls: 'labkey-text-link', + // href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Treatment Orders', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + // },{ + // xtype: 'ldk-linkbutton', + // text: 'Approved Requests', + // linkCls: 'labkey-text-link', + // style: 'padding-left: 5px;', + // href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Treatment Orders', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + // },{ + // xtype: 'ldk-linkbutton', + // text: 'Scheduled Today', + // linkCls: 'labkey-text-link', + // style: 'padding-left: 5px;', + // href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Treatment Orders', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + // }] + // } + //}, + //items: [{ + // //name: 'ASB Services', + // name: 'Treatment Orders Request', + // chargeType: 'DCM: Colony Services' + // + //}] + + //},{ + + //header: 'Treatment Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Drug Administration', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Drug Administration', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Scheduled Today', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Drug Administration', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + }] + } + }, + items: [{ + //name: 'ASB Services', + name: 'Treatment Given Request', + chargeType: 'DCM: Colony Services' + + }] + + },{ + //header: 'Procedure Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'encounters', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Pending', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'encounters', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType}) + },{ + xtype: 'ldk-linkbutton', + text: 'Scheduled Today', + linkCls: 'labkey-text-link', + style: 'padding-left: 5px;', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'encounters', 'query.viewName': 'Requests', 'query.QCState/Label~eq': 'Request: Approved', 'query.chargetype~eq': item.chargeType, 'query.date~dateeq': (new Date()).format('Y-m-d')}) + }] + } + }, + items: [{ + //name: 'ASB Services', + name: 'Procedure Request', + chargeType: 'DCM: Colony Services' + + }] + },{ + header: 'Lab Tests', + renderer: function(item){ + return item; + }, + items: [{ + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: 'Clinpath:', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Requests With Manual Results', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Clinpath Runs', 'query.viewName': 'Requests', 'query.QCState/Label~startswith': 'Request:', 'query.servicerequested/chargetype~eq': 'Clinpath', 'query.mergeSyncInfo/automaticresults~eq': false}) + },{ + xtype: 'ldk-linkbutton', + text: 'Requests With Automatic Results', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Clinpath Runs', 'query.viewName': 'Requests', 'query.QCState/Label~startswith': 'Request:', 'query.servicerequested/chargetype~eq': 'Clinpath', 'query.mergeSyncInfo/automaticresults~eq': true}) + }] + },{ + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: 'SPF Surveillance:', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'All Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'study', 'query.queryName': 'Clinpath Runs', 'query.QCState/Label~startswith': 'Request:', 'query.servicerequested/chargetype~eq': 'SPF Surveillance Lab'}) + }] + }] + + },{ + header: 'Transfer Requests', + renderer: function(item){ + return { + layout: 'hbox', + bodyStyle: 'padding: 2px;background-color: transparent;', + defaults: { + border: false + }, + items: [{ + html: item.name + ':', + width: 200 + },{ + xtype: 'ldk-linkbutton', + text: 'Unapproved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, Ext4.apply({schemaName: 'onprc_ehr', 'query.queryName': 'housing_transfer_requests', 'query.viewName': 'Unapproved Requests'}, item.areaFilter)) + },{ + xtype: 'ldk-linkbutton', + text: 'Approved Requests', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, Ext4.apply({schemaName: 'onprc_ehr', 'query.queryName': 'housing_transfer_requests', 'query.viewName': 'Approved Requests'}, item.areaFilter)) + },{ + xtype: 'ldk-linkbutton', + text: 'Transfers Today', + linkCls: 'labkey-text-link', + href: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, Ext4.apply({schemaName: 'onprc_ehr', 'query.queryName': 'housing_transfer_requests', 'query.viewName': 'Approved Requests', 'query.date~dateeq': (new Date()).format('Y-m-d')}, item.areaFilter)) + }] + } + }, + items: [{ + name: 'Corral', + chargeType: 'DCM: Colony Services', + areaFilter: { + 'query.room/area~eq': 'Corral' + } + },{ + name: 'PENS/Shelters', + chargeType: 'DCM: ASB Services', + areaFilter: { + 'query.room/area~in': 'PENS;Shelters' + } + },{ + name: 'All Other', + areaFilter: { + 'query.room/area~notin': 'Corral;PENS;Shelters' + } + }] + }] + }] + }] + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/LockAnimalsPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/LockAnimalsPanel.js index 58132adf7..3541dd8ac 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/LockAnimalsPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/LockAnimalsPanel.js @@ -115,6 +115,9 @@ Ext4.define('ONPRC_EHR.panel.LockAnimalsPanel', { togglePanel: function(locked){ var btn = this.down('#lockBtn'); + //btn.setText(locked ? 'Unlock Entry' : 'Lock Entry'); + btn.setText(locked ? 'Exit data entry' : 'Enable the form for data entry'); + btn.locked = !locked; var up = this.dataEntryPanel.getUpperPanel(); diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/ManageCasesPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/ManageCasesPanel.js new file mode 100644 index 000000000..d7a0b837d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/panel/ManageCasesPanel.js @@ -0,0 +1,1074 @@ +/* + * Copyright (c) 2013-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @cfg {String} animalId + */ + +//Created: 1-22-2018 R.Blasa + +Ext4.define('ONPRC_EHR.panel.ManageCasesPanel', { + extend: 'Ext.panel.Panel', + alias: 'widget.onprc_ehr-managecasespanel', + + statics: { + CASE_CATEGORIES: { + Clinical: { + showAssignedVet: true, + requiredFields: ['assignedvet', 'problem'] + }, + Weight: { + showAssignedVet: true, + requiredFields: ['assignedvet', 'problem'] + }, + Surgery: { + showAssignedVet: false, + requiredFields: ['remark'] + }, + Behavior: { + showAssignedVet: false, + requiredFields: ['problem', 'subcategory'] + } + }, + + getButtonConfig: function(){ + return [{ + xtype: 'button', + text: 'Open Case', + disabled: !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'insert', [{schemaName: 'study', queryName: 'Cases'}]), + menu: [{ + text: 'Open Behavior Case', + handler: function(btn){ + var owner = btn.up('window'); + if (owner) + owner = owner.down('panel'); + + owner.showCreateWindow('Behavior'); + } + },{ + text: 'Open Clinical Case', + handler: function(btn){ + var owner = btn.up('window'); + if (owner) + owner = owner.down('panel'); + + owner.showCreateWindow('Clinical'); + } + },{ + text: 'Open Surgery Case', + handler: function(btn){ + var owner = btn.up('window'); + if (owner) + owner = owner.down('panel'); + + owner.showCreateWindow('Surgery'); + } + }] + },{ + xtype: 'button', + text: 'Show Inactive', + handler: function(btn){ + var owner = btn.up('window'); + if (owner) + owner = owner.down('panel'); + + var store = owner.getStore(); + LDK.Assert.assertNotEmpty('Unable to find animalId in ManageCasesPanel', owner.animalId); + var filterArray = [ + LABKEY.Filter.create('Id', owner.animalId, LABKEY.Filter.Types.EQUAL) + ]; + + if (btn.text == 'Show Inactive'){ + btn.setText('Hide Inactive'); + } + else { + btn.setText('Show Inactive'); + filterArray.push(LABKEY.Filter.create('isOpen', true, LABKEY.Filter.Types.EQUAL)); + } + + store.filterArray = filterArray; + store.load(); + } + }] + } + }, + + initComponent: function(){ + Ext4.apply(this, { + border: false, + items: [this.getGridConfig()], + buttons: this.hideButtons ? null : this.getButtonConfig() + }); + + this.callParent(); + + this.addEvents('storeloaded'); + }, + + getStore: function(){ + if (this.store) + return this.store; + + this.store = Ext4.create('LABKEY.ext4.data.Store', { + schemaName: 'study', + queryName: 'Cases', + columns: 'lsid,objectid,Id,date,enddate,reviewdate,category,remark,performedby,problemCategories,encounterid,assignedvet,assignedvet/DisplayName,isOpen,isActive', + filterArray: [ + LABKEY.Filter.create('Id', this.animalId, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('isOpen', true, LABKEY.Filter.Types.EQUAL) + ], + autoLoad: true, + listeners: { + scope: this, + synccomplete: function(store){ + var grid = this.down('grid'); + if (grid){ + grid.getView().refresh(); + } + + EHR.DemographicsCache.clearCache(this.animalId); + }, + load: function(store){ + //NOTE: consumed by SnapshotPanel + this.fireEvent('storeloaded', this); + }, + exception: function(store){ + //NOTE: refresh the store in order to avoid invalid data on the client + store.load(); + } + } + }); + + return this.store; + }, + + getGridConfig: function(){ + return { + xtype: 'grid', + cls: 'ldk-grid', //variable row height + border: false, + store: this.getStore(), + viewConfig: { + loadMask: !(Ext4.isIE && Ext4.ieVersion <= 8) + }, + columns: [{ + xtype: 'actioncolumn', + width: 40, + icon: LABKEY.ActionURL.getContextPath() + '/_images/editprops.png', + tooltip: 'Edit', + handler: function(view, rowIndex, colIndex, item, e, rec){ + Ext4.create('Ext.menu.Menu', { + items: [{ + text: 'Close Case', + disabled: !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'update', [{schemaName: 'study', queryName: 'Cases'}]), + scope: this, + handler: function(btn){ + Ext4.create('Ext.window.Window', { + modal: true, + closeAction: 'destroy', + bodyStyle: 'padding: 5px', + width: 400, + items: [{ + html: 'This will close this case and all open problems. If you only want to close one of the problems, but leave the others open, please use \'Edit Case\' and only close the desired problem.', + border: false, + style: 'padding-bottom: 10px;' + },{ + xtype: 'datefield', + itemId: 'dateField', + fieldLabel: 'Close Date', + value: new Date(), //Modified: 10-09-2018 R.Blasa restored to original code + minValue: rec.get('date'), + maxValue: new Date() //Modified: 10-09-2018 R.Blasa restored to original code + }], + buttons: [{ + text: 'Close Case', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + var val = win.down('#dateField').getValue(); + if (!val){ + Ext4.Msg.alert('Error', 'Must choose a date'); + return; + } + + rec.set('enddate', val); + + Ext4.Msg.wait('Saving...'); + var store = rec.store; + store.sync({ + scope: this, + success: function(){ + Ext4.Msg.hide(); + store.load(); + } + }); + + win.close(); + } + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }).show(); + } + },{ + text: 'Close With Reopen Date', + disabled: !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'update', [{schemaName: 'study', queryName: 'Cases'}]), + scope: this, + handler: function(btn){ + Ext4.create('Ext.window.Window', { + title: 'Close With Reopen Date', + modal: true, + closeAction: 'destroy', + bodyStyle: 'padding: 5px', + width: 400, + items: [{ + html: 'This will close this case until the date selected below.', + border: false, + style: 'padding-bottom: 10px;' + },{ + xtype: 'datefield', + itemId: 'dateField', + fieldLabel: 'Reopen Date', + minValue: new Date(), //Modified: 10-09-2018 R.Blasa restored to original code + value: rec.get('reviewdate') || Ext4.Date.add(new Date(), Ext4.Date.DAY, 14) //Modified: 10-09-2018 R.Blasa restored to original code + }], + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + var val = win.down('#dateField').getValue(); + if (!val){ + Ext4.Msg.alert('Error', 'Must choose a date'); + return; + } + + rec.set('reviewdate', val); + rec.set('enddate', null); + var store = rec.store; + store.sync({ + scope: this, + success: function(){ + if (Ext4.Msg.isVisible()) + Ext4.Msg.hide(); + store.load(); + } + }); + + win.close(); + } + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }).show(); + } + },{ + text: 'Delete Case', + disabled: !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'delete', [{schemaName: 'study', queryName: 'Cases'}]), + handler: function(btn){ + Ext4.Msg.confirm('Delete Case', 'This will delete all record of this case. If you just want to close the case, you should choose this option instead. Are you sure you want to do this?', function(val){ + if (val == 'yes'){ + var store = rec.store; + store.remove(rec); + store.sync(); + } + }, this); + } + },{ + text: 'Edit Case', + disabled: !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'update', [{schemaName: 'study', queryName: 'Cases'}]), + scope: this, + handler: function(btn){ + this.up('onprc_ehr-managecasespanel').showEditCaseWindow(rec); + } + }] + }).showAt(e.getXY()); + } + },{ + header: 'Category', + dataIndex: 'category' + },{ + header: 'Active?', + dataIndex: 'isActive', + width: 60, + renderer: function(value){ + return value ? 'Y' : 'N'; + } + },{ + header: 'Open Date', + dataIndex: 'date', + xtype: 'datecolumn', + format: LABKEY.extDefaultDateFormat, + width: 130 + },{ + header: 'Reopen Date', + dataIndex: 'reviewdate', + xtype: 'datecolumn', + format: LABKEY.extDefaultDateFormat, + width: 130 + },{ + header: 'Description/Notes', + dataIndex: 'remark', + tdCls: 'ldk-wrap-text', + width: 250 + },{ + header: 'Vet', + dataIndex: 'assignedvet', + width: 130, + renderer: function(value, cellMetaData, record){ + if (Ext4.isDefined(record.get('assignedvet/DisplayName'))){ + return record.get('assignedvet/DisplayName'); + } + + return value ? '[' + value + ']' : value; + } + },{ + header: 'Problem(s)', + dataIndex: 'problemCategories', + tdCls: 'ldk-wrap-text', + renderer: function(v){ + if (v){ + return v.replace(/\n/g, '
'); + } + }, + width: 220 + }] + } + }, + + showEditCaseWindow: function(rec){ + if (Ext4.isArray(rec)){ + var data = []; + Ext4.Array.forEach(rec, function(r){ + var title = r.get('problemCategories') || r.get('remark'); + data.push({ + problems: r.get('problemCategories'), + title: title, + objectid: r.get('objectid'), + record: r + }); + }, this); + + Ext4.create('Ext.window.Window', { + title: 'Choose Case', + modal: true, + closeAction: 'destroy', + bodyStyle: 'padding: 5px;', + width: 420, + items: [{ + xtype: 'combo', + fieldLabel: 'Choose Case', + displayField: 'title', + triggerAction: 'all', + queryMode: 'local', + width: 400, + valueField: 'objectid', + store: { + type: 'store', + data: data, + fields: ['problems', 'objectid', 'record', 'title'] + }, + forceSelection: true + }], + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + var field = win.down('combo'); + if (!field.getValue()){ + Ext4.Msg.alert('Error', 'Must choose a case'); + return; + } + + var selected = field.store.findRecord('objectid', field.getValue()); + LDK.Assert.assertNotEmpty('Unable to find record in ManageCasesPanel', selected); + win.close(); + + Ext4.create('EHR.window.EditCaseWindow', { + boundRecord: selected.get('record') + }).show(); + } + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }).show(); + } + else { + Ext4.create('EHR.window.EditCaseWindow', { + boundRecord: rec + }).show(); + } + }, + + showCreateWindow: function(category, defaultRemark){ + var store = this.getStore(); + if (store.isLoading()){ + Ext4.Msg.wait('Loading...'); + store.on('load', function(){ + Ext4.Msg.hide(); + this.showCreateWindow(category, defaultRemark); + }, this, {single: true}); + return; + } + + var existingRecs = []; + store.each(function(r){ + if (r.get('category') == category && r.get('isActive')){ + existingRecs.push(r); + } + }, this); + + if (existingRecs.length){ + Ext4.create('Ext.window.MessageBox', { + buttonText: { yes: 'Open New', no: 'Edit Existing'} + }).show({ + icon: Ext4.Msg.QUESTION, + buttons: Ext4.Msg.YESNO, + title: 'Open Case', + msg: 'This animal already has an open ' + category + ' case. Do you want to edit this case or open a second one or edit the first?', + callback: function(val){ + if (val == 'yes'){ + Ext4.create('EHR.window.OpenCaseWindow', { + caseCategory: category, + ownerPanel: this, + animalId: this.animalId, + defaultVet: existingRecs[0].get('assignedvet'), + defaultRemark: defaultRemark + }).show(); + } + else if (val == 'no'){ + this.showEditCaseWindow(existingRecs.length == 1 ? existingRecs[0] : existingRecs); + } + }, + scope: this + }); + } + else { + Ext4.create('EHR.window.OpenCaseWindow', { + caseCategory: category, + ownerPanel: this, + animalId: this.animalId, + defaultRemark: defaultRemark + }).show(); + } + } +}); + +Ext4.define('EHR.window.EditCaseWindow', { + extend: 'Ext.window.Window', + + initComponent: function(){ + Ext4.apply(this, { + modal: true, + closeAction: 'destroy', + title: 'Edit Case', + width: 750, + bodyStyle: 'padding: 5px;', + items: [{ + xtype: 'form', + border: false, + defaults: { + labelWidth: 140, + border: false + }, + items: [{ + html: 'There are three dates for a case. The open date is the date is was created. If you enter a value for \'Date Closed\' means the date this case is completely closed, and will never re-open. If you want to temporarily close this case and reopen at a future date, enter a date in the \'Reopen Date\' field', + bodyStyle: 'padding-bottom: 10px;' + },{ + xtype: 'ehr-vetfieldcombo', + fieldLabel: 'Assigned Vet', + itemId: 'assignedvet', + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.boundRecord.get('category')].requiredFields.indexOf('assignedvet') == -1, + width: 560, + value: this.boundRecord.get('assignedvet') + },{ + xtype: 'datefield', + fieldLabel: 'Initial Open Date', + itemId: 'date', + allowBlank: false, + width: 560, + value: this.boundRecord.get('date') + },{ + xtype: 'datefield', + fieldLabel: 'Reopen Date', + itemId: 'reviewdate', + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.boundRecord.get('category')].requiredFields.indexOf('reviewdate') == -1, + width: 560, + value: this.boundRecord.get('reviewdate'), + listeners: { + change: function(field, val, oldVal){ + if (val){ + field.up('panel').down('#enddate').setValue(null); + } + } + } + },{ + xtype: 'datefield', + fieldLabel: 'Date Closed', + itemId: 'enddate', + allowBlank: true, + width: 560, + value: this.boundRecord.get('enddate') + },{ + xtype: 'textarea', + fieldLabel: 'Description/Notes', + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.boundRecord.get('category')].requiredFields.indexOf('remark') == -1, + width: 560, + height: 75, + value: this.boundRecord.get('remark'), + itemId: 'remark' + }] + },{ + xtype: 'ldk-gridpanel', + itemId: 'problemGrid', + title: 'Master Problems', + viewConfig: { + loadMask: !(Ext4.isIE && Ext4.ieVersion <= 8) + }, + store: { + type: 'labkey-store', + schemaName: 'study', + queryName: 'problem', + sort: 'date', + columns: 'Id,date,lsid,objectid,category,subcategory,enddate,caseid', + filterArray: [LABKEY.Filter.create('caseid', this.boundRecord.get('objectid'), LABKEY.Filter.Types.EQUAL)], + autoLoad: true, + listeners: { + exception: function(store){ + //NOTE: refresh the store in order to avoid invalid data on the client + store.load(); + } + } + }, + columns: [{ + xtype: 'actioncolumn', + width: 40, + icon: LABKEY.ActionURL.getContextPath() + '/_images/editprops.png', + tooltip: 'Edit', + handler: function(view, rowIndex, colIndex, item, e, rec){ + Ext4.create('EHR.window.CreateProblemWindow', { + title: 'Edit Problem', + caseRecord: view.up('window').boundRecord, + problemRecord: rec, + mode: 'edit', + problemStore: rec.store + }).show(); + } + },{ + dataIndex: 'category', + width: 180, + header: 'Problem' + },{ + dataIndex: 'subcategory', + width: 180, + header: 'Subcategory' + },{ + dataIndex: 'date', + header: 'Date', + xtype: 'datecolumn', + width: 180, + format: LABKEY.extDefaultDateFormat + },{ + dataIndex: 'enddate', + header: 'End Date', + xtype: 'datecolumn', + width: 180, + format: LABKEY.extDefaultDateFormat + }], + dockedItems: [{ + xtype: 'toolbar', + position: 'top', + items: [{ + text: 'Add', + scope: this, + handler: function(button){ + var grid = button.up('grid'); + LDK.Assert.assertNotEmpty('No bound record', this.boundRecord); + + Ext4.create('EHR.window.CreateProblemWindow', { + caseRecord: this.boundRecord, + problemStore: grid.store + }).show(); + } + },{ + text: 'End Selected', + scope: this, + handler: function(btn){ + var grid = btn.up('grid'); + var recs = grid.getSelectionModel().getSelection(); + if (!recs || !recs.length){ + Ext4.Msg.alert('Error', 'No problems selected'); + return; + } + + Ext4.Array.forEach(recs, function(r){ + if (!r.get('enddate')){ + r.set('enddate', new Date()); + } + }, this); + + Ext4.Msg.wait('Saving...'); + grid.store.sync({ + scope: this, + success: function(){ + Ext4.Msg.hide(); + }, + failure: LDK.Utils.getErrorCallback() + }); + } + }] + }] + }], + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + + if (!win.down('form').isValid()){ + Ext4.Msg.alert('Error', 'Missing one or more required fields'); + return; + } + + win.boundRecord.set({ + remark: win.down('#remark').getValue(), + assignedvet: win.down('#assignedvet').getValue(), + date: win.down('#date').getValue(), + reviewdate: win.down('#reviewdate').getValue() + }); + + win.boundRecord.set('assignedvet/DisplayName', win.down('#assignedvet').getDisplayValue()); + win.boundRecord.store.sync(); + + var problemGrid = win.down('#problemGrid'); + problemGrid.store.sync(); + + win.close(); + } + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }); + + this.callParent(arguments); + } +}); + + +/** + * @cfg caseCategory + * @cfg ownerPanel, + * @cfg animalId + * @cfg defaultVet + * @cfg defaultRemark + */ +Ext4.define('EHR.window.OpenCaseWindow', { + extend: 'Ext.window.Window', + + initComponent: function(){ + Ext4.apply(this, { + title: 'Open Case: ' + this.animalId, + width: 600, + modal: true, + closeAction: 'destroy', + bodyStyle: 'padding: 5px;', + items: [{ + xtype: 'form', + border: false, + defaults: { + border: false, + labelWidth: 140, + width: 550 + }, + items: [{ + xtype: 'displayfield', + fieldLabel: 'Category', + value: this.caseCategory, + name: 'category' + },{ + xtype: 'ehr-vetfieldcombo', + fieldLabel: 'Assigned Vet', + name: 'assignedvet', + value: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.caseCategory].showAssignedVet ? this.defaultVet : null, + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.caseCategory].requiredFields.indexOf('assignedvet') == -1, + hidden: !ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.caseCategory].showAssignedVet + },{ + xtype: 'labkey-combo', + fieldLabel: 'Problem', + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.caseCategory].requiredFields.indexOf('problem') == -1, + anyMatch: true, + queryMode: 'local', + forceSelection: true, + name: 'problem', + valueField: 'value', + displayField: 'value', + store: { + type: 'labkey-store', + schemaName: 'ehr_lookups', + queryName: 'problem_list_category', + autoLoad: true + }, + value: this.caseCategory == 'Behavior' ? 'Behavioral' : null, + listeners: { + change: function(field, val){ + var sc = field.up('window').down('#subcategory'); + sc.store.filterArray = [LABKEY.Filter.create('category', val)]; + sc.store.load(); + sc.setDisabled(false); + }, + render: function(field){ + if (field.getValue()){ + field.fireEvent('change', field, field.getValue()); + } + } + } + },{ + xtype: 'labkey-combo', + fieldLabel: 'Subcategory', + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.caseCategory].requiredFields.indexOf('subcategory') == -1, + valueField: 'value', + displayField: 'value', + itemId: 'subcategory', + name: 'subcategory', + disabled: true, + anyMatch: true, + queryMode: 'local', + forceSelection: true, + store: { + type: 'labkey-store', + schemaName: 'ehr_lookups', + queryName: 'problem_list_subcategory', + columns: 'value,category' + } + },{ + xtype: 'textarea', + fieldLabel: 'Description/Notes', + name: 'remark', + value: this.defaultRemark, + allowBlank: ONPRC_EHR.panel.ManageCasesPanel.CASE_CATEGORIES[this.caseCategory].requiredFields.indexOf('remark') == -1, + height: 75 + }] + }], + buttons: [{ + text: 'Open Case', + handler: function(btn){ + var win = btn.up('window'); + win.doSave(); //Modified: 12-20-2017 R.Blasa restored to original code + } + },{ + text: 'Open & Immediately Close', + menu: [{ + text: 'Close Permanently', + handler: function(btn){ + var win = btn.up('window'); + win.doSave(new Date()); //Modified: 12-20-2017 R.Blasa restored to original code + + } + },{ + text: 'Close With Reopen Date', + handler: function(btn){ + var ownerWindow = btn.up('window'); + if (!ownerWindow.down('form').getForm().isValid()){ + Ext4.Msg.alert('Error', 'Missing one or more required fields'); + return; + } + + Ext4.create('Ext.window.Window', { + modal: true, + closeAction: 'destroy', + bodyStyle: 'padding: 5px', + width: 400, + items: [{ + html: 'This will close this case until the date selected below.', + border: false, + style: 'padding-bottom: 10px;' + },{ + xtype: 'datefield', + itemId: 'dateField', + fieldLabel: 'Reopen Date', + minValue: new Date(), + value: Ext4.Date.add(new Date(), Ext4.Date.DAY, 14) + + }], + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + var val = win.down('#dateField').getValue(); + if (!val){ + Ext4.Msg.alert('Error', 'Must choose a date'); + return; + } + + win.close(); + ownerWindow.doSave(null, val); + } + }] + }).show(); + } + }] + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }); + + this.callParent(arguments); + }, + + doSave: function(enddate, reviewdate){ + if (!this.down('form').getForm().isValid()){ + Ext4.Msg.alert('Error', 'Missing one or more required fields'); + return; + } + + var values = this.down('form').getForm().getValues(); + var caseId = LABKEY.Utils.generateUUID().toUpperCase(); + values.date = new Date(); //Modified: 10-08-2018 R.Blasa restored to original code + values.category = this.caseCategory; + values.Id = this.ownerPanel.animalId; + values.performedby = LABKEY.Security.currentUser.displayName; + values.objectid = caseId; + if (enddate){ + values.enddate = enddate; + } + if (reviewdate){ + values.reviewdate = reviewdate; + } + + var problemRow = { + Id: values.Id, + date: values.date, + reviewdate: values.reviewdate, + enddate: values.enddate, + category: values.problem, + subcategory: values.subcategory, + caseid: values.objectid + }; + + var panel = this.ownerPanel; + + Ext4.Msg.wait('Saving...'); + + var commands = []; + commands.push({ + command: 'insertWithKeys', + schemaName: 'study', + queryName: 'cases', + rows: [{ + values: values + }] + }); + + commands.push({ + command: 'insert', + schemaName: 'study', + queryName: 'problem', + rows: [problemRow] + }); + + LABKEY.Query.saveRows({ + commands: commands, + scope: this, + failure: LDK.Utils.getErrorCallback(), + success: function(results){ + this.close(); + Ext4.Msg.hide(); + + EHR.DemographicsCache.reportCaseCreated(this.animalId, this.caseCategory, caseId); + + if (panel){ + panel.fireEvent('casecreated', this.animalId, this.caseCategory, caseId); + panel.down('grid').store.load(); + } + + EHR.DemographicsCache.clearCache(this.animalId); + } + }); + } +}); + +/** + * @cfg mode + * @cfg caseRecord + * @cfg problemRecord + */ +Ext4.define('EHR.window.CreateProblemWindow', { + extend: 'Ext.window.Window', + mode: 'insert', + + initComponent: function(){ + Ext4.apply(this, { + modal: true, + title: this.mode == 'edit' ? 'Edit Problem' : 'Add Problem', + bodyStyle: 'padding: 5px;', + defaults: { + width: 350 + }, + items: [{ + xtype: 'labkey-combo', + fieldLabel: 'Problem', + valueField: 'value', + displayField: 'value', + itemId: 'category', + anyMatch: true, + queryMode: 'local', + forceSelection: true, + value: this.problemRecord ? this.problemRecord.get('category') : null, + store: { + type: 'labkey-store', + schemaName: 'ehr_lookups', + queryName: 'problem_list_category', + autoLoad: true + }, + //Modified: 10-5-2018 R. Blasa filter array changes + listeners: { + change: function(field, val){ + var sc = field.up('panel').down('#subcategory'); + var initialValue = sc.getValue(); + sc.store.filterArray = [LABKEY.Filter.create('category', val),LABKEY.Filter.create('date_disabled', null, LABKEY.Filter.Types.ISBLANK)]; + sc.store.load({ + scope: this, + callback: function(){ + if (initialValue){ + sc.setValue(initialValue); + } + } + }); + sc.setDisabled(false); + }, + render: function(field){ + if (field.getValue()){ + field.fireEvent('change', field, field.getValue()); + } + } + } + },{ + xtype: 'labkey-combo', + fieldLabel: 'Subcategory', + valueField: 'value', + displayField: 'value', + itemId: 'subcategory', + value: this.problemRecord ? this.problemRecord.get('subcategory') : null, + disabled: (this.mode == 'insert') || !(this.problemRecord && this.problemRecord.get('category')), + anyMatch: true, + queryMode: 'local', + forceSelection: true, + store: { + type: 'labkey-store', + schemaName: 'ehr_lookups', + queryName: 'problem_list_subcategory', + columns: 'value,category', + filterArray: (this.problemRecord && this.problemRecord.get('category')) ? [LABKEY.Filter.create('category', this.problemRecord.get('category'))] : null, + autoLoad: (this.problemRecord && this.problemRecord.get('category')) + } + },{ + xtype: 'datefield', + fieldLabel: 'Open Date', + itemId: 'dateField', + maxValue: new Date(), //Modified: 10-08-2018 R.Blasa restored to original code + //cant open prior to case open + minValue: this.caseRecord.get('date'), + value: this.problemRecord ? this.problemRecord.get('date') : new Date() + },{ + xtype: 'datefield', + fieldLabel: 'End Date', + itemId: 'enddateField', + hidden: this.mode == 'insert', + //cant open prior to case open + minValue: this.caseRecord.get('date'), + value: this.problemRecord ? this.problemRecord.get('enddate') : null + }], + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + if (!win.down('#category').getValue() || !win.down('#dateField').getValue()){ + Ext4.Msg.alert('Error', 'Must enter the problem and date'); + return; + } + + if (win.mode == 'insert'){ + var newModel = win.problemStore.createModel({}); + newModel.set({ + Id: win.caseRecord.get('Id'), + caseid: win.caseRecord.get('objectid'), + category: win.down('#category').getValue(), + subcategory: win.down('#subcategory').getValue(), + date: win.down('#dateField').getValue() + }); + + win.problemStore.add(newModel); + } + else { + this.problemRecord.set({ + category: win.down('#category').getValue(), + subcategory: win.down('#subcategory').getValue(), + date: win.down('#dateField').getValue(), + enddate: win.down('#enddateField').getValue() + }); + } + + Ext4.Msg.wait('Saving...'); + win.problemStore.sync({ + scope: this, + success: function(){ + Ext4.Msg.hide(); + }, + failure: LDK.Utils.getErrorCallback() + }); + win.close(); + } + },{ + text: 'Delete', + hidden: !(this.mode == 'edit' && EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'delete', [{schemaName: 'study', queryName: 'Problem List'}])), + handler: function(btn){ + Ext4.Msg.confirm('Delete Problem', 'This will permanently delete this problem. Are you sure you want to do this?', function(val){ + if (val == 'yes'){ + var win = btn.up('window'); + var store = win.problemRecord.store; + store.remove(win.problemRecord); + + Ext4.Msg.wait('Saving...'); + store.sync({ + scope: this, + success: function(){ + Ext4.Msg.hide(); + }, + failure: LDK.Utils.getErrorCallback() + }); + win.close(); + } + }, this); + } + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }); + + this.callParent(arguments); + } +}); + diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/ManageTreatmentsPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/ManageTreatmentsPanel.js index cab3e2ce4..0e020a107 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/ManageTreatmentsPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/ManageTreatmentsPanel.js @@ -94,7 +94,7 @@ Ext4.define('onprc_ehr.panel.ManageTreatmentsPanel', { } }, config); - Ext4.create('EHR.window.ManageRecordWindow', cfg).show(); + Ext4.create('ONPRC_EHR.window.ManageRecordWindow', cfg).show(); //Modified: 7-18-2018 R.Blasa }, getActionBtnMenu: function(rec){ @@ -186,14 +186,14 @@ Ext4.define('onprc_ehr.panel.ManageTreatmentsPanel', { getStore: function(){ if (this.store) return this.store; - + var xdate = (new Date()).format('Y-m-d'); this.store = Ext4.create('LABKEY.ext4.data.Store', { schemaName: 'study', queryName: 'treatment_order', - columns: 'lsid,objectid,Id,date,enddate,project,category,remark,performedby,code,route,frequency,frequency/meaning,amountAndVolume,modifiedby/DisplayName,modified', + columns: 'lsid,objectid,Id,date,enddate,project,category,remark,performedby,code,route,frequency,frequency/meaning,amountAndVolume,modifiedby/DisplayName,modified,enddateTimeCoalesced', filterArray: [ LABKEY.Filter.create('Id', this.animalId, LABKEY.Filter.Types.EQUAL), - LABKEY.Filter.create('isExpired', false, LABKEY.Filter.Types.EQUAL) + LABKEY.Filter.create('enddateTimeCoalesced', xdate, LABKEY.Filter.Types.GTE)//Modified: 6-28-2018 R.Blasa ], autoLoad: true, listeners: { diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/MultiAnimalFilterType.js b/onprc_ehr/resources/web/onprc_ehr/panel/MultiAnimalFilterType.js new file mode 100644 index 000000000..f433f0f4d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/panel/MultiAnimalFilterType.js @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +//Created: 11-15-2017 R.Blasa + + +Ext4.define('EHR.panel.MultiAnimalFilterType', { + extend: 'LDK.panel.MultiSubjectFilterType', + alias: 'widget.onprc_ehr-multianimalfiltertype', + + statics: { + filterName: 'multiSubject', + label: 'Multiple Animals' + }, + + getItems: function(){ + var ctx = this.filterContext || {}; + + var toAdd = this.callParent(); + var items = [{ + layout: 'hbox', + border: false, + defaults: { + border: false + }, + items: toAdd + }] + + items.push({ + xtype: 'ldk-linkbutton', + text: '[Search By Room/Cage]', + minWidth: 80, + style: 'padding-left:200px;', + handler: function(btn){ + var panel = btn.up('onprc_ehr-multianimalfiltertype'); + + Ext4.create('Ext.window.Window', { + modal: true, + width: 330, + closeAction: 'destroy', + title: 'Search By Room/Cage', + items: [{ + xtype: 'form', + bodyStyle:'padding:5px', + items: [{ + xtype: 'ehr-roomfield', + itemId: 'room', + name: 'roomField', + multiSelect: false, + showOccupiedOnly: true, + width: 300 + },{ + xtype: 'ehr-cagefield', + fieldLabel: 'Cage', + name: 'cageField', + itemId: 'cage', + width: 300 + }] + }], + buttons: [{ + text:'Submit', + disabled:false, + itemId: 'submit', + scope: panel, + handler: panel.loadRoom + },{ + text: 'Close', + handler: function(btn){ + btn.up('window').hide(); + } + }] + }).show(btn); + } + }); + + items.push({ + xtype: 'ldk-linkbutton', + text: '[Search By Project/Protocol]', + minWidth: 80, + handler: function(btn){ + var panel = btn.up('onprc_ehr-multianimalfiltertype'); + + Ext4.create('Ext.window.Window', { + modal: true, + width: 330, + closeAction: 'destroy', + title: 'Search By Project/Protocol', + items: [{ + xtype: 'form', + bodyStyle:'padding:5px', + items: [{ + xtype: 'ehr-projectfield', + itemId: 'project', + onlyIncludeProjectsWithAssignments: true + },{ + xtype: 'ehr-protocolfield', + itemId: 'protocol', + onlyIncludeProtocolsWithAssignments: true + }] + }], + buttons: [{ + text:'Submit', + disabled:false, + itemId: 'submit', + scope: panel, + handler: panel.loadProject + },{ + text: 'Close', + handler: function(btn){ + btn.up('window').close(); + } + }] + }).show(btn); + }, + style: 'margin-bottom:10px;padding-left:200px;' + }); + //Added: 11-15-2017 R.Blasa + items.push({ + xtype: 'ldk-linkbutton', + text: '[Search By Animal Groups]', + minWidth: 80, + handler: function(btn){ + var panel = btn.up('onprc_ehr-multianimalfiltertype'); + + Ext4.create('Ext.window.Window', { + modal: true, + width: 300, + height:100, + closeAction: 'destroy', + title: 'Search By Animal Groups', + items: [{ + xtype: 'labkey-combo', + fieldLabel: '
Animal Groups
', + itemId: 'animalGroup', + displayField: 'name', + valueField: 'rowid', + store: { + type: 'labkey-store', + containerPath: ctx['EHRStudyContainer'], + schemaName: 'ehr', + queryName: 'animal_groups', + viewName: 'Active Groups', + columns: 'name, rowid', + filterArray: [LABKEY.Filter.create('enddate', null, LABKEY.Filter.Types.ISBLANK)], + autoLoad: true + } + }], + buttons: [{ + text:'Submit', + disabled:false, + itemId: 'submit', + scope: panel, + handler: panel.loadGroups + },{ + text: 'Close', + handler: function(btn){ + btn.up('window').close(); + } + }] + }).show(btn); + }, + style: 'margin-bottom:10px;padding-left:200px;' + }); + + + + return [{ + xtype: 'panel', + width: 500, + border: false, + defaults: { + border: false + }, + items: items + }]; + }, + + loadProject: function(btn){ + var win = btn.up('window'); + var project = win.down('#project').getValue(); + var protocol = win.down('#protocol').getValue(); + win.down('#project').reset(); + win.down('#protocol').reset(); + + win.close(); + + Ext4.Msg.wait("Loading.."); + + if(!project && !protocol){ + Ext4.Msg.hide(); + return; + } + + var filters = []; + + if(project){ + filters.push(LABKEY.Filter.create('project', project, LABKEY.Filter.Types.EQUAL)) + } + + if(protocol){ + protocol = protocol.toLowerCase(); + filters.push(LABKEY.Filter.create('project/protocol', protocol, LABKEY.Filter.Types.EQUAL)) + } + + LABKEY.Query.selectRows({ + schemaName: 'study', + queryName: 'Assignment', + viewName: 'Active Assignments', + sort: 'Id', + filterArray: filters, + scope: this, + success: function(rows){ + var subjectArray = []; + Ext4.each(rows.rows, function(r){ + subjectArray.push(r.Id); + }, this); + subjectArray = Ext4.unique(subjectArray); + if(subjectArray.length){ + this.tabbedReportPanel.setSubjGrid(true, false, subjectArray); + } + Ext4.Msg.hide(); + }, + failure: LDK.Utils.getErrorCallback() + }); + }, + + loadGroups: function(btn){ + var win = btn.up('window'); + var groups = win.down('#animalGroup').getValue(); + win.down('#animalGroup').reset(); + + win.close(); + + Ext4.Msg.wait("Loading.."); + + if(!groups){ + Ext4.Msg.hide(); + return; + } + + var filters = []; + + if(groups){ + filters.push(LABKEY.Filter.create('groupId/rowid', groups, LABKEY.Filter.Types.EQUAL)); + filters.push(LABKEY.Filter.create('enddate', null, LABKEY.Filter.Types.ISBLANK)) + } + + + LABKEY.Query.selectRows({ + schemaName: 'study', + queryName: 'animal_group_members', + //viewName: 'Active Assignments', + sort: 'Id', + filterArray: filters, + scope: this, + success: function(rows){ + var subjectArray = []; + Ext4.each(rows.rows, function(r){ + subjectArray.push(r.Id); + }, this); + subjectArray = Ext4.unique(subjectArray); + if(subjectArray.length){ + this.tabbedReportPanel.setSubjGrid(true, false, subjectArray); + } + Ext4.Msg.hide(); + }, + failure: LDK.Utils.getErrorCallback() + }); + }, + + loadRoom: function(btn){ + var housingWin = btn.up('window'); + var room = housingWin.down('#room').getValue(); + var cage = housingWin.down('#cage').getValue(); + housingWin.down('#room').reset(); + housingWin.down('#cage').reset(); + + housingWin.close(); + + Ext4.Msg.wait("Loading..."); + + if(!room && !cage){ + Ext4.Msg.hide(); + return; + } + + var filters = []; + + if(room){ + room = room.toLowerCase(); + filters.push(LABKEY.Filter.create('room', room, LABKEY.Filter.Types.STARTS_WITH)) + } + + if(cage){ + filters.push(LABKEY.Filter.create('cage', cage, LABKEY.Filter.Types.EQUAL)) + } + + LABKEY.Query.selectRows({ + schemaName: 'study', + queryName: 'housing', + viewName: 'Active Housing', + sort: 'Id', + filterArray: filters, + scope: this, + success: function(rows){ + var subjectArray = []; + Ext4.each(rows.rows, function(r){ + subjectArray.push(r.Id); + }, this); + subjectArray = Ext4.unique(subjectArray); + if(subjectArray.length){ + this.tabbedReportPanel.setSubjGrid(true, false, subjectArray); + } + Ext4.Msg.hide(); + }, + failure: LDK.Utils.getErrorCallback() + }); + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js index f3b6f088a..1543cd60d 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js @@ -258,7 +258,7 @@ Ext4.define('ONPRC.panel.RoomLayoutPanel', { } var animalItems = []; - if (animals.length > 4){ + if (animals.length > 8){ //Modified: 7-5-2018 R.Blasa animalItems.push({ html: '' + animals.length + ' animals', border: false, diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/ServiceRequestsPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/ServiceRequestsPanel.js new file mode 100644 index 000000000..e9c0d7fa2 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/panel/ServiceRequestsPanel.js @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created: 7-17-2017 R.Blasa + +Ext4.define('onprc_ehr.panel.ServiceRequestsPanel', { + extend: 'Ext.tab.Panel', + + minHeight: 300, + + initComponent: function(){ + Ext4.apply(this, { + items: this.getItems() + }); + + this.loadData(); + + this.callParent(); + }, + + loadData: function(){ + EHR.Utils.getDataEntryItems({ + includeFormElements: false, + scope: this, + success: this.onLoad + }); + }, + + onLoad: function(results){ + var formMap = {}; + Ext4.each(results.forms, function(form){ + if (form.canInsert && form.category == 'Requests'){ + formMap[form.category] = formMap[form.category] || []; + formMap[form.category].push({ + name: form.label, + url: LABKEY.ActionURL.buildURL('ehr', 'dataEntryForm', null, {formType: form.name}) + }); + } + }, this); + + var sections = []; + for (var i in formMap){ + var items = formMap[i]; + items = LDK.Utils.sortByProperty(items, 'name', false); + + if (items.length){ + sections.push({ + header: i, + items: items + }); + } + } + + var tab = this.down('#enterNew'); + tab.removeAll(); + + if (sections.length){ + tab.add({ + xtype: 'ldk-navpanel', + sections: sections + }); + } + else { + tab.add({ + html: 'You do not have permission to submit any types of requests. Please contact your administrator if you believe this is an error.', + border: false + }); + } + }, + + getItems: function(){ + return [{ +// xtype: 'ldk-querypanel', +// title: 'My Requests', +// style: 'padding: 5px;', +// queryConfig: { +// schemaName: 'ehr', +// queryName: 'my_requests' +// } +// },{ +// xtype: 'ldk-querypanel', +// title: 'All Requests', +// style: 'padding: 5px;', +// queryConfig: { +// schemaName: 'ehr', +// queryName: 'requests' +// } +// },{ + xtype: 'panel', + style: 'padding: 5px;', + title: 'New Request', + itemId: 'enterNew', + defaults: { + border: false + }, + items: [{ + html: 'Loading...' + }] + },{ + xtype: 'ldk-querypanel', + title: 'My Pending Blood Requests', + style: 'padding: 5px;', + queryConfig: { + schemaName: 'study', + queryName: 'blood', + viewName: 'Requests', + removeableFilters: [ + LABKEY.Filter.create('requestid/createdby/DisplayName', LABKEY.Security.currentUser.displayName, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('QCState/Label', 'Request', LABKEY.Filter.Types.STARTS_WITH) + ] + } + },{ + //Added: 7-18-2017 R.Blasa + xtype: 'ldk-querypanel', + title: 'My Pending Treatment Drugs Requests', + queryConfig: { + schemaName: 'study', + queryName: 'drug', + viewName: 'Requests', + removeableFilters: [ + LABKEY.Filter.create('requestid/createdby/DisplayName', LABKEY.Security.currentUser.displayName, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('QCState/Label', 'Request', LABKEY.Filter.Types.STARTS_WITH) + ] + } + },{ + //Modified: 1-5-2017 R.Blasa + xtype: 'ldk-querypanel', + title: 'My Pending Treatment Orders Requests', + queryConfig: { + schemaName: 'study', + queryName: 'Treatment Orders', + viewName: 'Requests', + removeableFilters: [ + //LABKEY.Filter.create('requestid/createdby/DisplayName', LABKEY.Security.currentUser.displayName, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('QCState/Label', 'Request', LABKEY.Filter.Types.STARTS_WITH) + ] + } + },{ + xtype: 'ldk-querypanel', + title: 'My Pending Labwork Requests', + queryConfig: { + schemaName: 'study', + queryName: 'Clinpath Runs', + viewName: 'Requests', + removeableFilters: [ + LABKEY.Filter.create('requestid/createdby/DisplayName', LABKEY.Security.currentUser.displayName, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('QCState/Label', 'Request', LABKEY.Filter.Types.STARTS_WITH) + ] + } + },{ + xtype: 'ldk-querypanel', + title: 'My Pending Procedure Requests', + queryConfig: { + schemaName: 'study', + queryName: 'encounters', + viewName: 'Requests', + removeableFilters: [ + LABKEY.Filter.create('requestid/createdby/DisplayName', LABKEY.Security.currentUser.displayName, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('QCState/Label', 'Request', LABKEY.Filter.Types.STARTS_WITH) + ] + } + },{ + xtype: 'ldk-querypanel', + title: 'My Pending Transfer Requests', + queryConfig: { + schemaName: 'onprc_ehr', + queryName: 'housing_transfer_requests', + //viewName: 'Requests', + removeableFilters: [ + LABKEY.Filter.create('requestid/createdby/DisplayName', LABKEY.Security.currentUser.displayName, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('QCState/Label', 'Request', LABKEY.Filter.Types.STARTS_WITH) + ] + } + }] + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js index fbf17cbff..60959f032 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js @@ -85,6 +85,10 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { xtype: 'displayfield', fieldLabel: 'Active Cases', name: 'activeCases' + },{ + xtype: 'displayfield', + fieldLabel: 'Behavior Alert' , + name: 'behaviorflag' }] },{ xtype: 'container', @@ -231,7 +235,7 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { - if (this.showExtendedInformation){ + if (this.showExtendedInformation){ this.appendBirthResults(toSet, results.getBirthInfo(), results.getBirth()); this.appendDeathResults(toSet, results.getDeathInfo()); this.appendParentageResults(toSet, results.getParents()); @@ -335,18 +339,22 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { }, - //Added: 2-21-2017 R.Blasa Display Infant cage mate under 1 yr + //Added: 4-20-2017 R.Blasa Display Infant cage mate under 1 yr appendFosterChildtResults: function(toSet, results){ - + var values = []; if (results) { - toSet['fosterinfants'] = results[0].FosterChild; - } - else - { - toSet['fosterinfants'] = 'None'; + Ext4.each(results, function(row){ + var foster = row.FosterChild; + + values.push(foster); + + }, this); + } + toSet['fosterinfants'] = values.length ? values.join('
') : 'None'; + }, @@ -385,7 +393,64 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { toSet['weights'] = text.length ? '' + text.join('') + '
' : null; }, + //Modified: 6-13-2017 R.Blasa + appendRoommateResults: function(toSet, results, id){ + var cagemates = 0; + var animals = []; + var pairingType; + + if (results && results.length){ + var row = results[0]; + if (row.animals){ + animals = row.animals.replace(/( )*,( )*/g, ','); + animals = animals.split(','); + animals.sort(); + animals = animals.remove(id); + + } + + pairingType = row.category; + } + + var values = []; + if (results){ + Ext4.each(results, function(row){ + if (row.animals){ + animals = row.animals.replace(/( )*,( )*/g, ','); + animals = animals.split(',') + animals.sort(); + animals = animals.remove(id); + values.push(animals); + + } + + }, this); + } + + //Modified: 8-22-2017 R.Blasa Provide link to Snapshot report + var url1 = '' + animals[0] +''; + var url2 = '' + animals[1] +''; + var url3 = '' + animals[2] +''; + toSet['cagemates'] = cagemates; + toSet['pairingType'] = pairingType; + + if (animals.length > 3){ + toSet['cagemates'] = animals.length + ' animals'; + } + else if (animals.length == 0){ + toSet['cagemates'] = 'None'; + } + else if (animals.length == 1) { + toSet['cagemates'] = url1; + } + else if (animals.length == 2) { + toSet['cagemates'] = url1 + '
' + url2 ; + } + else if (animals.length == 3) { + toSet['cagemates'] = url1 + '
' + url2 + '
' + url3; + } + }, appendParentageResults: function(toSet, results){ if (results){ var parentMap = {}; @@ -428,6 +493,67 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { } }, + //Modified: 5-10-2018 R.Blasa + appendFlags: function(toSet, results){ + var values = []; + var behavevalues = []; + var category; + if (results){ + Ext4.each(results, function(row){ + category = row['flag/category']; + var highlight = row['flag/category/doHighlight']; + var omit = row['flag/category/omitFromOverview']; + + //skip + if (omit === true) + return; + + if (category) + category = Ext4.String.trim(category); + + // var val = row['flag/value']; + var text ; + var behavetext; + + if (category == 'Behavior Flag') + { + behavetext = category + ': ' + row['flag/value']; + if (behavetext) + behavevalues.push(behavetext); + + } + else + { + text = category + ': ' + row['flag/value']; + if (text && highlight) + text = '' + text + ''; + if (text) + values.push(text); + } + + + }, this); + + if (values.length) { + values = Ext4.unique(values); + } + + if (behavevalues.length) { + behavevalues = Ext4.unique(behavevalues); + } + } + + toSet['flags'] = values.length ? '' + values.join('
') + '' : null; + + if (behavevalues.length) { + toSet['behaviorflag'] = behavevalues.length ? '
' + behavevalues.join('
') + '' : null; + } + else + { + toSet['behaviorflag'] = 'None' + } + }, + //Modified: 11-25-2016 R.Blasa getExtendedItems: function(){ return [{ diff --git a/onprc_ehr/resources/web/onprc_ehr/window/AddAnimalsWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/AddAnimalsWindow.js new file mode 100644 index 000000000..1e5e86487 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/window/AddAnimalsWindow.js @@ -0,0 +1,394 @@ +/* + * 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 + */ + +//Created: 1-9-2018 R.Blasa + +Ext4.define('EHR.window.AddAnimalsWindow', { + 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 + } + }], + 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 AddAnimalsWindow: ' + 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); + if(subjectList.length > 0){ + this.addSubjects(subjectList) + } + else { + Ext4.Msg.alert('Error', 'Must enter at least 1 animal Id'); + } + } + }, + + addSubjects: function(subjectList){ + 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){ + records.push(this.targetStore.createModel(Ext4.isObject(s) ? s : {Id: s})); + }, this); + + var choose = this.down('#chooseValues').getValue(); + if (choose){ + Ext4.create('EHR.window.BulkEditWindow', { + suppressConfirmMsg: true, + records: records, + targetStore: this.targetStore, + formConfig: this.formConfig + }).show(); + this.close(); + } + else { + this.targetStore.add(records); + } + } + + if (Ext4.Msg.isVisible()) + Ext4.Msg.hide(); + + this.close(); + }, + + 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 []; + }, + + animalGroupHandler: function(){ + var form = this.down('#theForm'); + form.removeAll(); + form.add([{ + html: 'This will return any animals currently assigned to the selected group. You are allowed to choose more than one animal gropu at a time.', + style: 'padding-bottom: 10px;' + },{ + xtype: 'onprc_ehr-animalgroupfield', + multiSelect: true, + emptyText: '', + itemId: 'groupField' + }]); + + form.getAnimals = function(){ + var group = this.down('#groupField').getValue(); + if (!group){ + Ext4.Msg.alert('Error', 'Must choose a group'); + return; + } + + var filterArray = this.getBaseFilterArray().concat([ + LABKEY.Filter.create('groupId', group.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF), + LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL) + ]); + + this.doQuery({ + schemaName: 'study', + queryName: 'animal_group_members', + filterArray: filterArray + }); + } + }, + + projectHandler: function(){ + var form = this.down('#theForm'); + form.removeAll(); + form.add([{ + html: 'This will return any animals currently assigned to the selected project or protocol. Choose one or the other.', + style: 'padding-bottom: 10px;' + },{ + xtype: 'ehr-projectfield', + emptyText: '', + itemId: 'projectField', + width: 400, + labelWidth: 140, + onlyIncludeProjectsWithAssignments: true + },{ + xtype: 'ehr-protocolfield', + emptyText: '', + itemId: 'protocolField', + width: 400, + labelWidth: 140, + onlyIncludeProtocolsWithAssignments: true + }]); + + form.getAnimals = function(){ + var projectId = this.down('#projectField').getValue(); + var protocol = this.down('#protocolField').getValue(); + if (!projectId && !protocol){ + Ext4.Msg.alert('Error', 'Must choose a project or protocol'); + return; + } + + if (projectId && protocol){ + Ext4.Msg.alert('Error', 'Cannot pick both a project and protocol'); + return; + } + + var filterArray = this.getBaseFilterArray().concat([LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL)]); + + if (projectId) + filterArray.push(LABKEY.Filter.create('project', projectId, LABKEY.Filter.Types.EQUAL)); + + if (protocol) + filterArray.push(LABKEY.Filter.create('project/protocol', protocol, LABKEY.Filter.Types.EQUAL)); + + this.doQuery({ + schemaName: 'study', + queryName: 'assignment', + filterArray: filterArray + }); + } + }, + + getAnimals: function(){ + 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 obj = { + Id: row.Id + }; + + if (hasLocation){ + obj['Id/curLocation/location'] = row['Id/curLocation/location']; + } + + records.push(obj); + } + }, this); + + this.addSubjects(records); + } +}); + +EHR.DataEntryUtils.registerGridButton('ADDANIMALST', function(config){ + return Ext4.Object.merge({ + text: 'Add Batch', + tooltip: 'Click to add a batch of animals, either as a list or by location', + handler: function(btn){ + var grid = btn.up('gridpanel'); + + Ext4.create('EHR.window.AddAnimalsWindow', { + targetStore: grid.store, + formConfig: grid.formConfig + }).show(); + } + }, config); +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/window/AddClinicalCasesWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/AddClinicalCasesWindow.js new file mode 100644 index 000000000..2ae50c16d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/window/AddClinicalCasesWindow.js @@ -0,0 +1,564 @@ + + +//Created: 10-24-2017 R.Blasa + +Ext4.define('EHR.window.AddClinicalCasesWindow', { + extend: 'Ext.window.Window', + caseCategory: 'Clinical', + templateName: 'Limited Visual Exam', + templateStoreId: 'Clinical Observations', + + allowNoSelection: false, + allowReviewAnimals: true, + showAssignedVetCombo: true, + caseDisplayField: 'problemCategories', + caseEmptyText: 'There are no problems associated with this case', + showAllowOpen: false, + + initComponent: function(){ + Ext4.applyIf(this, { + modal: true, + closeAction: 'destroy', + title: 'Add Open ' + this.caseCategory + ' Cases', + border: true, + bodyStyle: 'padding: 5px', + width: 420, + defaults: { + width: 400, + labelWidth: 150, + border: false + }, + items: [{ + html: 'This helper allows you to query open cases and add records for these animals.' + + (this.allowNoSelection ? ' Leave blank to load all areas.' : ''), + style: 'padding-bottom: 10px;' + },{ + xtype: 'ehr-areafield', + itemId: 'areaField' + },{ + xtype: 'ehr-roomfield', + itemId: 'roomField' + },{ + xtype: 'textarea', + fieldLabel: 'Animal(s)', + itemId: 'idField' + },{ + xtype: 'ehr-vetfieldcombo', + fieldLabel: 'Assigned Vet (blank for all)', + itemId: 'assignedVet', + hidden: !this.showAssignedVetCombo, + checked: true + },{ + xtype: 'xdatetime', + fieldLabel: 'Date', + value: new Date(), + itemId: 'date' + },{ + xtype: 'textfield', + fieldLabel: 'Entered By', + value: LABKEY.Security.currentUser.displayName, + itemId: 'performedBy' + },{ + xtype: 'checkbox', + fieldLabel: 'Exclude Animals w/ Obs Entered Today', + itemId: 'excludeToday', + checked: true + },{ + xtype: 'checkbox', + fieldLabel: 'Include Cases Closed For Review', + hidden: !this.showAllowOpen, + itemId: 'includeOpen', + checked: false + },{ + xtype: 'checkbox', + hidden: !this.allowReviewAnimals, + fieldLabel: 'Review Animals First', + itemId: 'reviewAnimals' + }], + buttons: [{ + text:'Submit', + itemId: 'submitBtn', + scope: this, + handler: this.getCases + },{ + text: 'Close', + scope: this, + handler: function(btn){ + btn.up('window').close(); + } + }] + }); + + this.callParent(arguments); + + if (this.templateName){ + LABKEY.Query.selectRows({ + schemaName: 'ehr', + queryName: 'formtemplates', + filterArray: [ + LABKEY.Filter.create('title', this.templateName), + LABKEY.Filter.create('formtype', 'Clinical Observations'), + LABKEY.Filter.create('category', 'Section') + ], + scope: this, + success: function(results){ + LDK.Assert.assertTrue('Unable to find template: ' + this.templateName, results.rows && results.rows.length == 1); + + this.obsTemplateId = results.rows[0].entityid; + }, + failure: LDK.Utils.getErrorCallback() + }); + } + }, + + getCasesFilterArray: function(){ + var filterArray = this.getBaseFilterArray(); + if (!filterArray) + return; + + var includeOpen = this.down('#includeOpen') ? this.down('#includeOpen').getValue() : false; + if (includeOpen){ + filterArray.push(LABKEY.Filter.create('isOpen', true, LABKEY.Filter.Types.EQUAL)); + } + else { + filterArray.push(LABKEY.Filter.create('isActive', true, LABKEY.Filter.Types.EQUAL)); + } + filterArray.push(LABKEY.Filter.create('category', this.caseCategory, LABKEY.Filter.Types.EQUAL)); + + if (this.down('#excludeToday').getValue()){ + filterArray.push(LABKEY.Filter.create('daysSinceLastRounds', 0, LABKEY.Filter.Types.GT)); + } + + var assignedVetField = this.down('#assignedVet'); + if (assignedVetField && assignedVetField.getValue()){ + filterArray.push(LABKEY.Filter.create('assignedvet', assignedVetField.getValue(), LABKEY.Filter.Types.EQUAL)); + } + + return filterArray; + }, + + getBaseFilterArray: function(){ + var area = this.down('#areaField').getValue() || []; + var rooms = EHR.DataEntryUtils.ensureArray(this.down('#roomField').getValue()) || []; + var ids = this.down('#idField').getValue(); + ids = LDK.Utils.splitIds(ids); + + if (!this.allowNoSelection && !area.length && !rooms.length && !ids.length){ + Ext4.Msg.alert('Error', 'Must provide at least one room or an area'); + return; + } + + if (ids.length && (rooms.length || area.length)){ + Ext4.Msg.alert('Error', 'Cannot search on both location and IDs at the same time'); + return; + } + + var filterArray = []; + + if (area.length) + filterArray.push(LABKEY.Filter.create('Id/curLocation/area', area.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); + + if (rooms.length) + filterArray.push(LABKEY.Filter.create('Id/curLocation/room', rooms.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); + + if (ids.length) + filterArray.push(LABKEY.Filter.create('Id', ids.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); + + return filterArray; + }, + + getCases: function(button){ + var filterArray = this.getCasesFilterArray(); + if (!filterArray || !filterArray.length){ + return; + } + + Ext4.Msg.wait("Loading..."); + this.hide(); + + //find distinct animals matching criteria + LABKEY.Query.selectRows({ + requiredVersion: 9.1, + schemaName: 'study', + queryName: 'cases', + sort: 'Id/curlocation/room_sortValue,Id/curlocation/cage_sortValue,Id', + columns: 'Id,Id/curLocation/location,objectid,mostRecentP2,Id/Utilization/use,problemCategories,mostRecentCeg_Plan', + filterArray: filterArray, + scope: this, + success: this.onSuccess, + failure: LDK.Utils.getErrorCallback() + }); + }, + + onSuccess: function(results){ + if (!results || !results.rows || !results.rows.length){ + Ext4.Msg.hide(); + Ext4.Msg.alert('', 'No active cases were found' + (this.down('#excludeToday').getValue() ? '. Note: you selected to exclude those with obs today.' : '.')); + this.close(); + + return; + } + + LDK.Assert.assertNotEmpty('Unable to find targetStore in AddClinicalCasesWindow', this.targetStore); + + var records = []; + this.caseRecordMap = {}; + this.recordData = { + performedby: this.down('#performedBy').getValue(), + date: this.down('#date').getValue() + } + + var idMap = {}; + + Ext4.Array.each(results.rows, function(sr){ + var row = new LDK.SelectRowsRow(sr); + idMap[row.getValue('Id')] = row; + this.caseRecordMap[row.getValue('objectid')] = row; + + var obj = { + Id: row.getValue('Id'), + date: this.recordData.date, + category: 'Clinical', + s: null, + o: null, + a: null, + p: null, + p2: row.getValue('mostRecentP2'), + caseid: row.getValue('objectid'), + remark: null, + CEG_Plan: row.getValue('mostRecentCeg_Plan'), //Added: 10-24-2017 R.Blasa + performedby: this.recordData.performedby, + 'Id/curLocation/location': row.getValue('Id/curLocation/location') + }; + + records.push(this.targetStore.createModel(obj)); + }, this); + + if (this.down('#reviewAnimals').getValue()){ + this.doReviewAnimals(records, idMap); + } + else { + this.addRecords(records); + } + }, + + doReviewAnimals: function(caseRecords, idMap){ + var toAdd = [{ + html: 'Id' + },{ + html: 'Projects/Groups' + },{ + html: 'Include' + }]; + + Ext4.Array.forEach(caseRecords, function(rec){ + var ar = idMap[rec.get('Id')]; + + toAdd.push({ + html: rec.get('Id') + }); + + toAdd.push({ + html: ar.getDisplayValue('Id/Utilization/use') ? ar.getDisplayValue('Id/Utilization/use') : 'None' + }); + + toAdd.push({ + xtype: 'checkbox', + record: rec, + checked: true + }); + }, this); + + Ext4.Msg.hide(); + Ext4.create('Ext.window.Window', { + title: 'Choose Animals To Add', + ownerWindow: this, + closeAction: 'destroy', + width: 450, + modal: true, + defaults: { + border: false + }, + items: [{ + border: false, + bodyStyle: 'padding: 5px;', + items: [{ + border: false, + defaults: { + border: false, + style: 'margin-right: 10px;' + }, + maxHeight: Ext4.getBody().getHeight() * 0.8, + autoScroll: true, + layout: { + type: 'table', + columns: 3 + }, + items: toAdd + },{ + layout: 'hbox', + style: 'padding-top: 15px;', + border: false, + items: [{ + xtype: 'ldk-linkbutton', + text: '[Check All]', + handler: function(btn){ + var cbs = btn.up('window').query('checkbox'); + Ext4.Array.forEach(cbs, function(item){ + item.setValue(true); + }); + } + },{ + border: false, + html: ' ' + },{ + xtype: 'ldk-linkbutton', + style: 'margin-left:5px;', + text: '[Uncheck All]', + handler: function(btn){ + var cbs = btn.up('window').query('checkbox'); + Ext4.Array.forEach(cbs, function(item){ + item.setValue(false); + }); + } + }] + }] + }], + buttons: [{ + xtype: 'button', + text: 'Submit', + scope: this, + handler: this.onSubmit + },{ + xtype: 'button', + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }).show(); + }, + + onSubmit: function(btn){ + var win = btn.up('window'); + var cbs = win.query('checkbox'); + + var records = []; + Ext4.Array.forEach(cbs, function(cb){ + if (cb.getValue()){ + records.push(cb.record); + } + }, this); + + win.close(); + + if (records.length){ + Ext4.Msg.wait('Loading...'); + this.addRecords(records); + } + else { + win.ownerWindow.close(); + } + }, + + addRecords: function(records){ + //check for duplicates + var ids = []; + var duplicateIds = []; + Ext4.Array.forEach(records, function(r){ + if (ids.indexOf(r.get('Id')) > -1){ + duplicateIds.push(r.get('Id')); + } + else { + ids.push(r.get('Id')); + } + }, this); + + if (!duplicateIds.length){ + this.doAddRecords(records); + } + else { + var items = [{ + html: 'Below are animals with multiple open cases. For each animal, select the case to review. Leave blank to skip that animal.', + style: 'padding-bottom: 10px;', + border: false + }]; + + duplicateIds = duplicateIds.sort(); + Ext4.Array.forEach(duplicateIds, function(id){ + //find matching records + var data = []; + Ext4.Array.forEach(records, function(r){ + if (r.get('Id') == id){ + var caseRec = this.caseRecordMap[r.get('caseid')]; + LDK.Assert.assertNotEmpty('Unable to find case record', caseRec); + + data.push({ + value: r.get('caseid'), + display: caseRec.getValue(this.caseDisplayField) || this.caseEmptyText, + caseRecord: r + }); + } + }, this); + + items.push({ + xtype: 'combo', + fieldLabel: id, + animalId: id, + width: 400, + queryMode: 'local', + valueField: 'value', + displayField: 'display', + store: { + type: 'store', + fields: ['value', 'display', 'record'], + data: data + } + }); + }, this); + + Ext4.Msg.hide(); + Ext4.create('Ext.window.Window', { + modal: true, + title: 'Duplicate Open Cases', + bodyStyle: 'padding: 5px', + width: 450, + items: items, + buttons: [{ + text: 'Submit', + scope: this, + handler: function(btn){ + var win = btn.up('window'); + var combos = win.query('combo'); + var map = {}; + Ext4.Array.forEach(combos, function(c){ + map[c.animalId] = c.getValue(); + }, this); + + var nonDupes = []; + Ext4.Array.forEach(records, function(r){ + if (!r){ + console.log('no record'); + return; + } + + if (map.hasOwnProperty(r.get('Id')) && r.get('caseid') != map[r.get('Id')]){ + //no need to actually remove. + //records.remove(r); + } + else { + nonDupes.push(r); + } + }, this); + + win.close(); + this.doAddRecords(nonDupes); + } + },{ + text: 'Cancel', + scope: this, + handler: function(btn){ + btn.up('window').close(); + this.close(); + } + }] + }).show(); + } + }, + + doAddRecords: function(records){ + var toAdd = this.checkForExistingCases(records); + if (toAdd.length){ + this.targetStore.add(toAdd); + + if (this.obsTemplateId){ + this.applyObsTemplate(toAdd); + } + else { + this.onComplete(); + } + } + else { + this.onComplete(); + } + }, + + checkForExistingCases: function(records){ + //check for existing caseids + var existingIds = {}; + this.targetStore.each(function(r){ + if (r.get('caseid')){ + existingIds[r.get('caseid')] = true; + } + }, this); + + var toAdd = []; + Ext4.Array.forEach(records, function(r){ + if (!existingIds[r.get('caseid')]){ + toAdd.push(r); + } + else { + this.hasSkippedDuplicates = true; + } + }, this); + + return toAdd; + }, + + onComplete: function(){ + Ext4.Msg.hide(); + this.close(); + + if (this.hasSkippedDuplicates){ + Ext4.Msg.alert('Skipped Animals', 'One or more cases were skipped because they are already in this form'); + } + }, + + applyObsTemplate: function(caseRecords){ + var records = []; + Ext4.Array.forEach(caseRecords, function(rec){ + records.push({ + Id: rec.get('Id'), + caseid: rec.get('caseid'), + date: this.recordData.date, + performedby: this.recordData.performedby + }); + }, this); + + EHR.window.ApplyTemplateWindow.loadTemplateRecords(function(recMap){ + if (!recMap || LABKEY.Utils.isEmptyObj(recMap)){ + this.onComplete(); + return; + } + + for (var i in recMap){ + var store = Ext4.StoreMgr.get(i); + store.add(recMap[i]); + } + + this.onComplete(); + }, this, this.targetStore.storeCollection, this.obsTemplateId, records); + } +}); + +EHR.DataEntryUtils.registerGridButton('ADDCLINICALCASES', function(config){ + return Ext4.Object.merge({ + text: 'Add Open Cases', + tooltip: 'Click to automatically add SOAP notes based on open cases', + handler: function(btn){ + var grid = btn.up('gridpanel'); + if(!grid.store || !grid.store.hasLoaded()){ + console.log('no store or store hasnt loaded'); + return; + } + + var cellEditing = grid.getPlugin('cellediting'); + if(cellEditing) + cellEditing.completeEdit(); + + Ext4.create('EHR.window.AddClinicalCasesWindow', { + targetStore: grid.store + }).show(); + } + }, config); +}); diff --git a/onprc_ehr/resources/web/onprc_ehr/window/BulkChangeCasesWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/BulkChangeCasesWindow.js index fb8eb0945..d3176019d 100644 --- a/onprc_ehr/resources/web/onprc_ehr/window/BulkChangeCasesWindow.js +++ b/onprc_ehr/resources/web/onprc_ehr/window/BulkChangeCasesWindow.js @@ -48,6 +48,7 @@ Ext4.define('ONPRC_EHR.window.BulkChangeCasesWindow', { caseIds.push(rec.get('caseid')); }, this); + //Modified: 9-10-2018 R.Blasa caseIds = Ext4.unique(caseIds); LABKEY.Query.selectRows({ schemaName: 'study', @@ -56,7 +57,7 @@ Ext4.define('ONPRC_EHR.window.BulkChangeCasesWindow', { scope: this, failure: LDK.Utils.getErrorCallback(), success: this.onLoad, - columns: 'objectid,Id,date,remark,category,reviewdate,enddate' + columns: 'objectid,Id,date,remark,category,reviewdate,lsid,enddate' }); }, diff --git a/onprc_ehr/resources/web/onprc_ehr/window/BulkStrokeRoundsWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/BulkStrokeRoundsWindow.js index 3abdcb1fa..bbb6e7666 100644 --- a/onprc_ehr/resources/web/onprc_ehr/window/BulkStrokeRoundsWindow.js +++ b/onprc_ehr/resources/web/onprc_ehr/window/BulkStrokeRoundsWindow.js @@ -97,13 +97,13 @@ Ext4.define('ONPRC_EHR.window.BulkStrokeRoundsWindow', { errors.push('Row ' + rowIdx + ': not enough items in row'); continue; } - var id = parsed[0][1]; + var id = Ext4.String.trim(parsed[0][1]); if (!id){ errors.push('Row ' + rowIdx + ': missing Id'); return; } - var procedure = parsed[5][1]; - var narrative = parsed[6][1]; + var procedure = Ext4.String.trim(parsed[5][1]); + var narrative = Ext4.String.trim(parsed[6][1]); //var project = this.resolveProjectByName(parsed[4][1], errors, rowIdx); var project = EHR.DataEntryUtils.getDefaultClinicalProject(); var cnt = i; @@ -121,7 +121,7 @@ Ext4.define('ONPRC_EHR.window.BulkStrokeRoundsWindow', { //Procedure if (recordMap.encounters.length){ var clientStore = this.dataEntryPanel.storeCollection.getClientStoreByName('encounters'); - LDK.Assert.assertNotEmpty('Unable to find procedure store in BulkStrokeRoundsWindow', clientStore); + LDK.Assert.assertNotEmpty('Unable to find procedure store in BulkStrokeRoundsWindow ', clientStore); var records = []; for (var i=0;i -1){ + return; + } + + if (!Ext4.isEmpty(row.getValue(field.name))) + obj[field.name] = row.getValue(field.name); + }, this); + + var model = serverStore.addServerModel({}); + model.set(obj); + + this.toAddMap[serverStore.storeId].push(model); + }, this); + } + } + }); + }, this); + + multi.send(this.onLoad, this); + }, + + onLoad: function(){ + Ext4.Msg.hide(); + if (!Ext4.Object.isEmpty(this.toAddMap)){ + for (var storeId in this.toAddMap){ + var targetStore = this.dataEntryPanel.storeCollection.serverStores.get(storeId); + LDK.Assert.assertNotEmpty('Unable to find server store: ' + storeId, targetStore); + + targetStore.suspendEvents(); + targetStore.add(this.toAddMap[storeId]); + targetStore.resumeEvents(); + } + + this.dataEntryPanel.storeCollection.transformServerToClient(); + } + else { + Ext4.Msg.alert('No Records', 'There are no records to add'); + } + + this.close(); + } +}); + +EHR.DataEntryUtils.registerDataEntryFormButton('COPY_TASKS', { + text: 'Copy Previous Task', + name: 'copyFromTask', + itemId: 'copyFromTask', + tooltip: 'Click to copy records from a previously created task', + handler: function(btn){ + var dataEntryPanel = btn.up('ehr-dataentrypanel'); + LDK.Assert.assertNotEmpty('Unable to find dataentrypanel in COPY_TASKS', dataEntryPanel); + + Ext4.create('onprc_ehr.window.CopyTaskWindow', { + dataEntryPanel: dataEntryPanel + }).show(); + } +}); + diff --git a/onprc_ehr/resources/web/onprc_ehr/window/ManageCasesWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/ManageCasesWindow.js new file mode 100644 index 000000000..4b29415f8 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/window/ManageCasesWindow.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @cfg {String} animalId + */ + +//Created: 1-22-2018 R.Blasa + +Ext4.define('ONPRC_EHR.window.ManageCasesWindow', { + extend: 'EHR.window.ManageCasesWindow', + + width: 1100, + minHeight: 50, + + initComponent: function(){ + Ext4.apply(this, { + title: 'Manage Cases: ' + this.animalId, + modal: true, + closeAction: 'destroy', + items: [{ + xtype: 'onprc_ehr-managecasespanel', + animalId: this.animalId, + date:this.date, + hideButtons: true + }], + buttons: this.getButtonConfig() + }); + + this.callParent(arguments); + }, + + getButtonConfig: function(){ + var buttons = ONPRC_EHR.panel.ManageCasesPanel.getButtonConfig(); + buttons.push({ + text: 'Close', + handler: function(btn){ + btn.up('window').close(); + } + }); + + return buttons; + } +}); + + + + + diff --git a/onprc_ehr/resources/web/onprc_ehr/window/ManageRecordWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/ManageRecordWindow.js new file mode 100644 index 000000000..4c8bada9d --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/window/ManageRecordWindow.js @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2013-2015 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @cfg schemaName + * @cfg queryName + * @cfg pkCol + * @cfg pkValue + */ +Ext4.define('ONPRC_EHR.window.ManageRecordWindow', { + extend: 'Ext.window.Window', + + statics: { + buttonHandler: function(Id, objectId, queryName, dataRegionName){ + LDK.Assert.assertNotEmpty('No objectid provided to ManageRecordWindow.buttonHandler', objectId); + LDK.Assert.assertNotEmpty('No queryName provided to ManageRecordWindow.buttonHandler', queryName); + + Ext4.create('ONPRC_EHR.window.ManageRecordWindow', { + schemaName: 'study', + queryName: queryName, + maxItemsPerCol: 11, + pkCol: 'objectid', + pkValue: objectId, + listeners: { + scope: this, + save: function(){ + if (dataRegionName && LABKEY.DataRegions[dataRegionName]){ + LABKEY.DataRegions[dataRegionName].refresh(); + } + } + } + }).show(); + } + }, + initComponent: function(){ + Ext4.apply(this, { + modal: true, + closeAction: 'destroy', + minWidth: 600, + minHeight: 200, + items: [{ + border: false, + style: 'padding: 5px;', + html: 'Loading...' + }], + buttons: [{ + text: 'Submit', + scope: this, + requiredQC: 'Completed', + targetQC: 'Completed', + errorThreshold: 'INFO', + disableOn: 'WARN', + disabled: true, + handler: this.onSubmit + },{ + text: 'Re-validate Form', + scope: this, + handler: function(btn){ + var form = this.down('#formPanel'); + var rec = form.getRecord(); + if (!rec) + return; + + this.down('#dataEntryPanel').storeCollection.validateAll(); + } + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }] + }); + + this.callParent(); + this.addEvents('save'); + + LABKEY.Ajax.request({ + url: LABKEY.ActionURL.buildURL('ehr', 'dataEntryFormJsonForQuery', null), + params: { + schemaName: this.schemaName, + queryName: this.queryName + }, + scope: this, + failure: LDK.Utils.getErrorCallback(), + success: LABKEY.Utils.getCallbackWrapper(this.onFormLoad, this) + }) + }, + + onSubmit: function(btn) { + var form = this.down('#formPanel'); + var rec = form.getRecord(); + if (!rec) + return; + if (!rec.get('taskid')) { + var tsk = LABKEY.Utils.generateUUID().toUpperCase(); + LABKEY.Query.insertRows({ + schemaName: 'ehr', + queryName: 'tasks', + rows: [{ + taskid: tsk, + formtype: 'treatments', + title: 'Medication/Diet', + assignedto: LABKEY.Security.currentUser.userid, + qcstate: 18, + datecompleted: new Date(), + category: 'Task' + }], + scope: this, + failure: EHR.Utils.onError, + success: function () { + Ext.Msg.hide(); + } + }); + rec.set('taskid', tsk); + } + this.down('#dataEntryPanel').onSubmit(btn); + }, + onFormLoad: function(results){ + this.formResults = results; + this.setTitle(this.formResults.formConfig.label); + + if (results.cssDependencies){ + LABKEY.requiresCss(results.cssDependencies); + } + + if (results.jsDependencies){ + LABKEY.requiresScript(results.jsDependencies, this.onJsLoad, this, true); + } + else { + this.onJsLoad(); + } + }, + + onJsLoad: function(){ + var name = Ext4.id(); + + Ext4.define(name, { + extend: this.formResults.formConfig.javascriptClass, + alias: 'widget.' + name, + extraMetaData: this.extraMetaData, + applyConfigToServerStore: function(cfg){ + cfg = this.callParent(arguments); + cfg.filterArray = cfg.filterArray || []; + cfg.filterArray.push(LABKEY.Filter.create(this.pkCol, this.pkValue, LABKEY.Filter.Types.EQUAL)); + + return cfg; + }, + onStoreCollectionInitialLoad: function(){ + var item = this.getItemConfig()[0]; + item.itemId = 'formPanel'; + item.maxItemsPerCol = item.maxItemsPerCol || 9; + item.maxFieldWidth = EHR.form.Panel.defaultFieldWidth; + + var win = this.ownerWindow; + if (win.maxItemsPerCol) + item.maxItemsPerCol = win.maxItemsPerCol; + + var formPanel = Ext4.widget(item); + var cols = formPanel.items.get(0).items.getCount(); + var width = cols * (EHR.form.Panel.defaultFieldWidth + 10); + + formPanel.down('#columnPanel').setWidth(width); + + this.removeAll(); + this.add(formPanel); + win.removeAll(); + win.setWidth(width + 20); + win.add(this); + win.center(); + + this.hasStoreCollectionLoaded = true; + }, + getToolbarItems: function(){ + var win = this.up('window'); + if (!win){ + //NOTE: this can occur once after the window is closed, but before the store returns + return; + } + + return win.getDockedItems('toolbar[dock="bottom"]'); + }, + getButtons: function(){ + return []; + } + }); + + var dataEntryPanel = Ext4.widget({ + xtype: name, + ownerWindow: this, + itemId: 'dataEntryPanel', + pkCol: this.pkCol, + pkValue: this.pkValue, + hideErrorPanel: true, + formConfig: this.formResults.formConfig, + onStoreCollectionCommitComplete: this.onStoreCollectionCommitComplete + }); + }, + + onStoreCollectionCommitComplete: function(sc, extraContext){ + Ext4.Msg.hide(); + var win = this.up('window'); + win.fireEvent('save', this, sc); + win.close(); + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/window/MarkAssignmentCompletedWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/MarkAssignmentCompletedWindow.js index c7707fe8e..7c0054798 100644 --- a/onprc_ehr/resources/web/onprc_ehr/window/MarkAssignmentCompletedWindow.js +++ b/onprc_ehr/resources/web/onprc_ehr/window/MarkAssignmentCompletedWindow.js @@ -43,7 +43,7 @@ Ext4.define('ONPRC_EHR.window.MarkAssignmentCompletedWindow', { }, bodyStyle: 'padding: 5px;', items: [{ - html: 'This helper allows you to end the selected assignments. You are required to choose the end date, and release type. If release condition is left blank, the projected release condition will be used.', + html: 'This helperT allows you to end the selected assignments. You are required to choose the end date, and release type. If release condition is left blank, the projected release condition will be used.', width: 470, style: 'padding-bottom: 10px;' },{ @@ -69,6 +69,9 @@ Ext4.define('ONPRC_EHR.window.MarkAssignmentCompletedWindow', { schemaName: 'ehr_lookups', queryName: 'animal_condition', columns: 'code,meaning', + filterArray: [ + LABKEY.Filter.create('datedisabled',null, LABKEY.Filter.Types.ISBLANK) + ], autoLoad: true, sort: 'code' } diff --git a/onprc_ehr/resources/web/onprc_ehr/window/ONPRC_AddScheduledTreatmentWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/ONPRC_AddScheduledTreatmentWindow.js index a66f6d1f2..7478dddb3 100644 --- a/onprc_ehr/resources/web/onprc_ehr/window/ONPRC_AddScheduledTreatmentWindow.js +++ b/onprc_ehr/resources/web/onprc_ehr/window/ONPRC_AddScheduledTreatmentWindow.js @@ -59,26 +59,27 @@ Ext4.define('ONPRC_EHR.window.AddScheduledTreatmentWindow', { xtype: 'ehr-roomfield', itemId: 'roomField' },*/{ - xtype: 'checkcombo', - forceSelection: true, - multiSelect: true, - addAllSelector: true, - fieldLabel: 'Treatment Time', - itemId: 'timeField', - displayField: 'treatmentTime', - valueField: 'timeValue', - store: { - type: 'array', - fields: ['timeValue','treatmentTime'], - data: [ - ['800', '8:00 AM'], - ['1200', '12:00 Noon'], - ['1600', '4:00 PM'], - ['2000', '8:00 PM'] - ] - } - },{ - xtype: 'ehr-snomedtreatmentcombo', + xtype: 'checkcombo', + forceSelection: true, + multiSelect: true, + addAllSelector: true, + fieldLabel: 'Treatment Time', + itemId: 'timeField', + displayField: 'treatmentTime', + valueField: 'timeValue', + store: { + type: 'array', + fields: ['timeValue','treatmentTime'], + data: [ + ['800', '8:00 AM'], + ['1200', '12:00 Noon'], + ['1400', '2:00 PM'], + ['1600', '4:00 PM'], + ['2000', '8:00 PM'] + ] + } + }, + {xtype: 'onprc-snomedtreatmentcombo', //Modified 6-22-2015 Blasa defaultSubset: 'Post Op Meds' , fieldLabel: 'Treatment(s)', itemId: 'code' diff --git a/onprc_ehr/resources/web/onprc_ehr/window/SurgeryPostOpMedsWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/SurgeryPostOpMedsWindow.js new file mode 100644 index 000000000..671580d94 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/window/SurgeryPostOpMedsWindow.js @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +// Created: 10-4-2017 R.Blasa + + +Ext4.define('onprc_ehr.window.SurgeryPostOpMedsWindow', { + extend: 'Ext.window.Window', + + initComponent: function(){ + Ext4.apply(this, { + modal: true, + closeAction: 'destroy', + title: 'Order Post-Op Meds', + minWidth: 820, + bodyStyle: 'padding: 5px;', + buttons: [{ + text: 'Submit', + scope: this, + handler: this.onSubmit + },{ + text: 'Close', + handler: function(btn){ + btn.up('window').close(); + } + }], + items: [{ + html: 'Loading...', + border: false + }] + }); + + this.callParent(arguments); + + var store = this.getFrequencyStore(); + store.on('load', this.onStoreLoad, this); + }, + + getFrequencyStore: function(){ + if (this.frequencyStore) + return this.frequencyStore; + + this.frequencyStore = Ext4.create('LABKEY.ext4.data.Store', { + schemaName: 'ehr_lookups', + queryName: 'treatment_frequency', + columns: 'rowid,meaning,times', + autoLoad: true + }); + + return this.frequencyStore; + }, + + onStoreLoad: function(store){ + var ids = []; + this.encountersStore.each(function(r, recIdx){ + if (!r.get('Id') || !r.get('procedureid')){ + return; + } + + ids.push(r.get('Id')); + }); + + ids = Ext4.unique(ids); + + EHR.DataEntryUtils.getWeights(this.targetStore.storeCollection, ids, this.onDemographicsLoad, this, false); + }, + + onDemographicsLoad: function(weightMap){ + this.weightMap = weightMap; + this.removeAll(); + this.add(this.getItems()); + this.center(); + }, + + getItems: function(){ + var numCols = 7; + var items = [{ + xtype: 'displayfield', + value: 'Animal Id' + },{ + xtype: 'displayfield', + value: 'Procedure' + },{ + xtype: 'displayfield', + value: 'Weight' + },{ + xtype: 'displayfield', + value: 'Surg. Time' + },{ + xtype: 'displayfield', + value: '1st Dose' + },{ + xtype: 'displayfield', + value: 'Analgesia' + },{ + xtype: 'displayfield', + value: 'Antibiotics' + }]; + + var ids = []; + this.encountersStore.each(function(r, recIdx){ + if (!r.get('Id') || !r.get('procedureid')){ + return; + } + + items.push({ + xtype: 'displayfield', + value: r.get('Id'), + width: 100, + recIdx: recIdx + }); + + var procedureRec = this.getProcedureRec(r.get('procedureid')); + LDK.Assert.assertNotEmpty('Unable to find procedure matching rowid: ' + r.get('procedureid'), procedureRec); + items.push({ + xtype: 'displayfield', + width: 200, + value: procedureRec.get('name'), + recIdx: recIdx + }); + + if (ids.indexOf(r.get('Id')) > -1){ + items.push({ + xtype: 'displayfield', + value: 'Duplicate Animal', + colspan: (numCols - 2) + }); + + return; + } + ids.push(r.get('Id')); + + items.push({ + xtype: 'displayfield', + value: this.weightMap[r.get('Id')] ? this.weightMap[r.get('Id')].weight : '', + recIdx: recIdx + }); + + if (r.get('date')){ + items.push({ + xtype: 'displayfield', + value: r.get('date').format('H:i'), + recIdx: recIdx + }); + + //start meds on either 1200/1600/2000, 3 hours offset form surg time + var hour = r.get('date').getHours(); + hour += 3; + + //note: if more than 30 mins past the hour, round up + if (r.get('date').getMinutes() >= 30){ + hour++; + } + + if (hour > 16){ + hour = 20; + } + else if (hour > 12){ + hour = 16; + } + else { + hour = 12; + } + + var time = new Date(); + Ext4.Date.clearTime(time); + time.setHours(hour); + + items.push({ + xtype: 'timefield', + fieldName: 'time', + minValue: '8:00', + maxValue: '20:00', + increment: 240, + width: 80, + format: 'H:i', + value: time, + recIdx: recIdx + }); + } + else { + items.push({ + xtype: 'displayfield', + value: 'No Date' + }); + + items.push({ + xtype: 'displayfield', + value: null + }); + } + + items.push({ + xtype: 'labkey-combo', + forceSelection: true, + width: 225, + valueField: 'entityid', + displayField: 'title', + fieldName: 'analgesiaRx', + encountersRec: r, + store: this.getTemplateStoreCfg(recIdx, procedureRec, 'analgesiaRx'), + recIdx: recIdx + }); + + items.push({ + xtype: 'labkey-combo', + forceSelection: true, + width: 225, + valueField: 'entityid', + displayField: 'title', + fieldName: 'antibioticRx', + encountersRec: r, + store: this.getTemplateStoreCfg(recIdx, procedureRec, 'antibioticRx'), + recIdx: recIdx + }); + }, this); + + return { + border: false, + style: 'padding-top: 10px', + defaults: { + style: 'margin-right: 5px;' + }, + layout: { + type: 'table', + columns: numCols + }, + items: items + }; + }, + + getTemplateStoreCfg: function(recIdx, procedureRec, fieldName){ + return { + type: 'labkey-store', + schemaName: 'ehr', + queryName: 'my_formtemplates', + initialTemplate: procedureRec.get(fieldName), + fieldName: fieldName, + recIdx: recIdx, + sort: 'title', + autoLoad: true, + filterArray: [ + LABKEY.Filter.create('formtype', 'Treatment Orders', LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('category', 'Section', LABKEY.Filter.Types.EQUAL) + ], + listeners: { + scope: this, + load: function(store){ + LDK.Assert.assertTrue('No records found in SurgeryPostOpMeds store', store.getCount() > 0); + + if (store.initialTemplate){ + var recIdx = store.findExact('title', store.initialTemplate); + if (recIdx != -1){ + var entityId = store.getAt(recIdx).get('entityid'); + var combo = this.down('combo[recIdx=' + store.recIdx + '][fieldName=' + store.fieldName + ']'); + LDK.Assert.assertNotEmpty('Unable to find combo for field: ' + store.fieldName, combo); + + if (combo){ + combo.setValue(entityId); + } + } + } + } + } + } + }, + + getProcedureRec: function(procedureId){ + var procedureRecIdx = EHR.DataEntryUtils.getProceduresStore().findExact('rowid', procedureId); + if (procedureRecIdx != -1){ + return EHR.DataEntryUtils.getProceduresStore().getAt(procedureRecIdx); + } + }, + + onSubmit: function(){ + var combos = this.query('combo[encountersRec]'); + this.templateMap = {}; + Ext4.Array.forEach(combos, function(combo){ + if (combo.getValue()){ + this.templateMap[combo.getValue()] = this.templateMap[combo.getValue()] || []; + this.templateMap[combo.getValue()].push(combo.encountersRec); + } + }, this); + + if (Ext4.Object.isEmpty(this.templateMap)){ + Ext4.Msg.alert('Error', 'Must choose at least one template'); + return; + } + + this.hide(); + LABKEY.Query.selectRows({ + requiredVersion: 9.1, + schemaName: 'ehr', + queryName: 'formtemplaterecords', + filterArray: [LABKEY.Filter.create('templateid', Ext4.Object.getKeys(this.templateMap).join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)], + scope: this, + failure: LDK.Utils.getErrorCallback(), + success: this.onTemplateLoad + }); + }, + + getFrequencyRec: function(meaning){ + if (!meaning) + return null; + + var frequencyIdx = this.getFrequencyStore().findExact('meaning', meaning, 0, false, false, true); + LDK.Assert.assertTrue('Unable to find frequency for: ' + meaning, frequencyIdx > -1); + + if (frequencyIdx > -1){ + return this.getFrequencyStore().getAt(frequencyIdx); + } + }, + + onTemplateLoad: function(results){ + if (!results || !results.rows || !results.rows.length){ + this.close(); + Ext4.Msg.alert('', 'No rows found for the selected templates'); + return; + } + + //build map of values + var templateRowMap = {}; + Ext4.Array.forEach(results.rows, function(row){ + row = new LDK.SelectRowsRow(row); + + var templateId = row.getValue('templateid'); + templateRowMap[templateId] = templateRowMap[templateId] ||[]; + + templateRowMap[templateId].push(row); + }, this); + + var combos = this.query('combo[encountersRec]'); + var records = []; + Ext4.Array.forEach(combos, function(combo){ + if (combo.getValue()){ + var encountersRec = combo.encountersRec; + var timeField = this.query('timefield[recIdx=' + combo.recIdx + ']')[0]; + + var toAdd = templateRowMap[combo.getValue()]; + if (toAdd){ + Ext4.Array.forEach(toAdd, function(templateRow){ + var json = templateRow.getValue('json'); + if (json){ + json = Ext4.decode(json); + + var date = Ext4.Date.clone(encountersRec.get('date')); + date = Ext4.Date.clearTime(date); + date.setHours(timeField.getValue().getHours()); + + //Modifed:10-4-2017 R.Blasa + if (json.offset){ + var offsetDate = Ext4.Date.add(Ext4.Date.clone(date), Ext4.Date.DAY, json.offset); + //offsetDate = Ext4.Date.clearTime(offsetDate); + //offsetDate.setHours(times[0] / 100); + date = offsetDate; + } + + //always set start to be the first normal dose after the start time + var frequencyRec = this.getFrequencyRec(json.frequency_meaning); + var frequency = frequencyRec ? frequencyRec.get('rowid') : null; + if (frequencyRec && frequencyRec.get('times')){ + var times = frequencyRec.get('times').split(','); + date = EHR.DataEntryUtils.getNextDoseTime(date, times); + } + + var enddate = null; + if (json.duration){ + //this is specifically to handle hydro, when administered ~noon + if (new String(json.duration).match(/H$/)){ + var duration = new String(json.duration); + duration = duration.replace('H', ''); + duration = Number(duration); + duration += encountersRec.get('date').getHours(); + duration = Math.floor(duration / 24); + + enddate = Ext4.Date.clone(encountersRec.get('date')); + endate = Ext4.Date.clearTime(enddate); + enddate = Ext4.Date.add(enddate, Ext4.Date.DAY, duration); + } + else { + enddate = Ext4.Date.clone(date); + enddate = Ext4.Date.add(enddate, Ext4.Date.DAY, json.duration); + } + + //always assume a full day, so end at the last scheduled time + var hour = 23; + if (frequencyRec && frequencyRec.get('times')){ + var times = frequencyRec.get('times').split(','); + hour = times[times.length - 1]; + hour = Math.min(hour / 100); + } + + enddate.setHours(hour); + } + + var obj = { + Id: encountersRec.get('Id'), + parentid: encountersRec.get('objectid'), + project: encountersRec.get('project'), + date: date, + enddate: enddate, + frequency: frequency + }; + + Ext4.apply(obj, json); + + //this isnt great, but hard code amount on hydro and buprenex for now + if (obj.code == 'E-77851' || obj.code == 'E-YY792'){ + var weight = this.weightMap[encountersRec.get('Id')] ? this.weightMap[encountersRec.get('Id')].weight : null; + if (weight){ + obj.amount_units = 'mg'; + obj.vol_units = 'mL'; + + //hyrdo + if (obj.code == 'E-77851'){ + if (weight < 3.0){ + obj.amount = 0.5; + obj.volume = 0.25; + } + else if (weight < 10.0){ + obj.amount = 1.0; + obj.volume = 0.5; + } + else { + obj.amount = 2.0; + obj.volume = 1.0; + } + } + //buprenex + else if (obj.code == 'E-YY792'){ + if (weight < 3.0){ + obj.amount = 0.15; + obj.volume = 0.5; + } + else { + obj.amount = 0.3; + obj.volume = 1.0; + } + } + } + } + + records.push(this.targetStore.createModel(obj)); + } + }, this); + } + else { + console.log('Unable to find template: ' + combo.getValue()); + } + } + }, this); + + if (records.length){ + this.targetStore.add(records); + } + + this.close(); + } +}); + +EHR.DataEntryUtils.registerGridButton('SURGERYMEDS', function(config){ + config = config || {}; + + return Ext4.Object.merge({ + text: 'Order Post-Op Meds', + itemId: 'postOpBtn', + handler: function(btn){ + var grid = btn.up('gridpanel'); + LDK.Assert.assertNotEmpty('Unable to find gridpanel in SURGERYMEDS button', grid); + + var encountersStore = grid.store.storeCollection.getClientStoreByName('encounters'); + LDK.Assert.assertNotEmpty('Unable to find encountersStore in SURGERYMEDS button', encountersStore); + + Ext4.create('onprc_ehr.window.SurgeryPostOpMedsWindow', { + targetStore: grid.store, + encountersStore: encountersStore + }).show(); + } + }); +}); \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRManager.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRManager.java index d4d77cb87..e58afaa63 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRManager.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRManager.java @@ -50,6 +50,8 @@ public class ONPRC_EHRManager @Queryable public static final String U24_PROJECT = "0492-03"; @Queryable + public static final String JMAC_PROJECT = "0492-45"; + @Queryable public static final String TMB_PROJECT = "0300"; @Queryable public static final String VET_USER_GROUP = "DCM Veterinarians"; diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 2a89a4f33..3d1049709 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -77,7 +77,9 @@ import org.labkey.onprc_ehr.history.DefaultAnimalRecordFlagDataSource; import org.labkey.onprc_ehr.history.DefaultNHPTrainingDataSource; import org.labkey.onprc_ehr.history.DefaultSnomedDataSource; +import org.labkey.onprc_ehr.history.ONPRCClinicalRemarksDataSource; import org.labkey.onprc_ehr.history.ONPRCUrinalysisLabworkType; +import org.labkey.onprc_ehr.history.ONPRCiStatLabworkType; import org.labkey.onprc_ehr.notification.*; import org.labkey.onprc_ehr.security.ONPRC_EHRCMUAdministrationPermission; import org.labkey.onprc_ehr.security.ONPRC_EHRCMUAdministrationRole; @@ -92,9 +94,9 @@ import java.util.Collections; /** - * User: bbimber - * Date: 5/16/12 - * Time: 1:52 P + * User: jonesga + * Date: 6/26/2018 + * Change of ONPRC Module Number */ public class ONPRC_EHRModule extends ExtendedSimpleModule { @@ -110,7 +112,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 18.10; + return 17.705; } @Override @@ -158,6 +160,20 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext) //Added 3-8-2017 Blasa ns.registerNotification(new ObeseFlagNotification(this)); + //Added 4-25-2017 R.Blasa + ns.registerNotification(new InfantsBornAssignedNotification(this)); + + //Added April, 2017 Kollil + ns.registerNotification(new PregnantNHPsGestationAlert(this)); + + //Added May 12th, 2017 Kollil + ns.registerNotification(new DCMNotesNotification(this)); + + //Added May 12th, 2017 Kollil + ns.registerNotification(new BSUNotesNotification(this)); + + //Added 8-7-2018 R.Blasa + ns.registerNotification(new BirthHousingMismatchNotification(this)); ns.registerNotification(new RequestAdminNotification(this)); ns.registerNotification(new ColonyAlertsLiteNotification(this)); @@ -210,6 +226,28 @@ private void registerEHRResources() EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/NarrowSnapshotPanel.js"), this); + + //Added: 10-25-2017 R.Blasa References new Xtype + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/CEG_PlantextArea.js"), this); + + //Added: 7-7-2017 R.Blasa +// EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/HousingReason.js"), this); + + //Added: 1-19-2018 R.Blasa + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/AnimalGroupFieldsCombo.js"), this); + +// //Added: 10-5-2018 R.Blasa //needed for displaying wound subcategory + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/panel/ManageCasesPanel.js"), this); + + // //Added: 10-8-2018 R.Blasa //needed for displaying wound subcategory + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageCasesWindow.js"), this); + + + //Added: 7-18-2018 R.Blasa + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageRecordWindow.js"), this); + + + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single Housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=demographicsPaired&query.viewName=Single Housed"), "Commonly Used Queries"); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "Find Animals Housed In A Given Room/Cage At A Specific Time", this, DetailsURL.fromString("/ehr/housingOverlaps.view?groupById=1"), "Commonly Used Queries"); @@ -247,6 +285,9 @@ private void registerEHRResources() //Added 1-30-2017 R.Blasa EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Snapshot Printable Report", this, DetailsURL.fromString("/onprc_ehr/SnapshotPrintableReport.view"), "Clinical"); + //Added 5-16-2018 R.Blasa + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Date of Last Physical Exam by ID(s)", this, DetailsURL.fromString("/onprc_ehr/PE_ExamHistoryReportbyID.view"), "Routine Clinical Tasks"); + //Added 5-11-2015 New report for Lois Colgin try { @@ -265,6 +306,24 @@ public String toString() throw new UnexpectedException(e); } + //Added 6-21-2017 R.Blasa + try + { + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Basic Exposure Report", this, new URLHelper("http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fExposure+Report%2fBasicExposureMain&rs:Command=Render") + { + // SSRS is picky about the URI-encoding of the query parameters + @Override + public String toString() + { + return "http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fExposure+Report%2fBasicExposureMain&rs:Command=Render"; + } + }, "Exposure Report"); + } + catch (URISyntaxException e) + { + throw new UnexpectedException(e); + } + try { EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Colony Census Excel Workbook", this, new URLHelper(AppProps.getInstance().getContextPath() + "/onprc_ehr/reports/Colony Census.xlsm"), "Colony Management"); @@ -294,9 +353,19 @@ public String toString() EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Mense Data With Cycle Date", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=menseData"), "Reproductive Management"); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=tissueDistributionSummary"), "Pathology"); + // Added: 1-2-2018 R.Blasa + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary(Calendar Year)", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=TissueDistributionSummaryCalendarYr"), "Pathology"); + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "SNOMED Search", this, DetailsURL.fromString("/onprc_ehr/snomedSearch.view"), "Pathology"); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary, By Recipient", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=tissueDistributionSummaryByRecipient"), "Pathology"); +// Added 1-2-2018 R.Blasa + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary, By Recipient(Calendar Year)", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=tissueDistributionSummaryByRecipientCalendarYr"), "Pathology"); + + //Added: 12-7-2017 R.Blasa + // EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Animal Census on a Given Date Range", this, DetailsURL.fromString("/onprc_ehr/CensusGivenDateRange.view"), "Colony Management"); + + EHRService.get().registerActionOverride("projectDetails", this, "views/projectDetails.html"); EHRService.get().registerActionOverride("protocolDetails", this, "views/protocolDetails.html"); EHRService.get().registerActionOverride("procedureDetails", this, "views/procedureDetails.html"); @@ -306,6 +375,9 @@ public String toString() EHRService.get().registerActionOverride("animalHistory", this, "views/animalHistory.html"); EHRService.get().registerActionOverride("serviceRequests", this, "views/serviceRequests.html"); + //Added: 10-2-2017 R.Blasa displays onperc version of enterData.view + EHRService.get().registerActionOverride("enterData", this, "views/enterData.html"); + //data entry EHRService.get().registerFormType(new DefaultDataEntryFormFactory(WeightFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(AnesthesiaFormType.class, this)); @@ -341,6 +413,7 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(MatingFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PregnancyConfirmationFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ParentageFormType.class, this)); + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(GeneticAncestryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ONPRCBloodDrawFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(AuxProcedureFormType.class, this)); @@ -355,11 +428,20 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(DrugRequestBulkEditFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(LabworkRequestBulkEditFormType.class, this)); + +// Added: 11-21-2017 R.Blasa + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ProcedureRequestBulkEditFormType.class, this)); + + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(RecordAmendmentFormType.class, this)); //Added: 10-19-2016 R.Blasa EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NHPTrainingFormType.class, this)); + //Added: 4-5-2017 R.Blasa + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NHPRProcessingFormType.class, this)); + + //single section forms EHRService.get().registerSingleFormOverride(new SingleQueryFormProvider(this, "study", "treatment_order", new MedicationsQueryFormSection("study", "Treatment Orders", "Medication/Treatment Orders"))); EHRService.get().registerSingleFormOverride(new SingleQueryFormProvider(this, "study", "drug", new MedicationsQueryFormSection("study", "Drug Administration", "Medication/Treatments Given"))); @@ -369,6 +451,7 @@ public String toString() EHRService.get().registerDemographicsProvider(new CagematesDemographicsProvider(this)); EHRService.get().registerDemographicsProvider(new HousingDemographicsProvider(this)); EHRService.get().registerDemographicsProvider(new ParentsDemographicsProvider(this)); + EHRService.get().registerDemographicsProvider(new GeneticAncestryDemographicsProvider(this)); EHRService.get().registerDemographicsProvider(new SourceDemographicsProvider(this)); EHRService.get().registerDemographicsProvider(new ActiveFlagsDemographicsProvider(this)); EHRService.get().registerDemographicsProvider(new TBDemographicsProvider(this)); @@ -378,6 +461,8 @@ public String toString() //Created: 1-20-2017 R.Blasa EHRService.get().registerDemographicsProvider(new PregnancyConfirmDemographicsProvider(this)); + //Added: 3-27-2017 R.Blasa + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/panel/EnterDataPanel.js"), this); //Created: 2-21-2017 R.Blasa EHRService.get().registerDemographicsProvider(new CagemateInfantDemographicsProvider(this)); @@ -387,6 +472,10 @@ public String toString() //Created: 3-10-2017 R.Blasa EHRService.get().registerDemographicsProvider(new FosterChildDemographicsProvider(this)); + + //Created: 4-7-2015-10-2017 R.Blasa + EHRService.get().registerDemographicsProvider(new ActiveTreatmentsXDemographicsProvider(this)); + //buttons EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "my_tasks"); EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "tasks"); @@ -420,6 +509,11 @@ public String toString() EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Labwork", LabworkFormType.NAME), "study", "clinpathRuns"); EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); + + //Added: 7-29-2017 R.Blasa + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); + + EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this), "study", "blood"); EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this, "ONPRC_EHR.window.ChangeLabworkStatusWindow", Collections.singletonList(ClientDependency.supplierFromPath("onprc_ehr/window/ChangeLabworkStatusWindow.js"))), "study", "clinpathRuns"); EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this), "onprc_ehr", "housing_transfer_requests"); @@ -446,14 +540,22 @@ public String toString() EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "tissue_samples"); EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "organ_weights"); - EHRService.get().registerOptionalClinicalHistoryResources(this); +// Added: 10-9-2017 R.Blasa + EHRService.get().registerMoreActionsButton(new BulkEditRequestsButton(this, ProcedureRequestBulkEditFormType.NAME), "study", "encounters"); + EHRService.get().registerHistoryDataSource(new DefaultSnomedDataSource(this)); EHRService.get().registerHistoryDataSource(new DefaultAnimalGroupsDataSource(this)); EHRService.get().registerHistoryDataSource(new DefaultAnimalGroupsEndDataSource(this)); //R.Blasa 3-4-2015 EHRService.get().registerHistoryDataSource(new DefaultAnimalRecordFlagDataSource(this)); + //R.Blasa 1-23-2015 + EHRService.get().registerHistoryDataSource(new org.labkey.api.ehr.history.DefaultAnimalRecordFlagDataSource(this)); + EHRService.get().registerHistoryDataSource(new ONPRCClinicalRemarksDataSource(this)); + + EHRService.get().registerOptionalClinicalHistoryResources(this); EHRService.get().registerLabworkType(new ONPRCUrinalysisLabworkType(this)); + EHRService.get().registerLabworkType(new ONPRCiStatLabworkType(this)); //R.Blasa 11-28-2016 EHRService.get().registerHistoryDataSource(new DefaultNHPTrainingDataSource(this)); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ASBRequestFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ASBRequestFormType.java index c121a72c0..e933e8832 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ASBRequestFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ASBRequestFormType.java @@ -26,14 +26,10 @@ import java.util.Arrays; -/** - * User: bimber - * Date: 7/29/13 - * Time: 5:03 PM - */ +//Modified: 12-21-2016 R.blasa public class ASBRequestFormType extends RequestForm { - public static final String NAME = "ASB Services Request"; + public static final String NAME = "ASB SERVICES REQUEST"; public static final String DEFAULT_GROUP = "ASB Services"; public ASBRequestFormType(DataEntryFormContext ctx, Module owner) @@ -42,9 +38,12 @@ public ASBRequestFormType(DataEntryFormContext ctx, Module owner) new RequestFormSection(), //new RequestInstructionsFormSection(), new AnimalDetailsFormSection(), - new BloodDrawFormSection(true) + new ClinicalEncountersFormSection(), + new BloodDrawFormSection(true), + +// Modified: 7-18-2017 R.Blasa - // new DrugAdministrationRequestFormSection() Removed 6/17/2015 GJONES ISsue 1820 + new DrugAdministrationRequestFormSection() )); addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/ASB_Services.js")); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AuxProcedureFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AuxProcedureFormType.java index f2788d8a0..a900f3b46 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AuxProcedureFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AuxProcedureFormType.java @@ -70,7 +70,6 @@ public AuxProcedureFormType(DataEntryFormContext ctx, Module owner) protected List getButtonConfigs() { List ret = super.getButtonConfigs(); - ret.add("APPLYFORMTEMPLATE"); return ret; @@ -80,7 +79,7 @@ protected List getButtonConfigs() protected List getMoreActionButtonConfigs() { List defaultButtons = super.getMoreActionButtonConfigs(); - defaultButtons.add("COPY_TASK"); + defaultButtons.add("COPY_TASKS"); defaultButtons.add("BULK_BLOOD_DRAW"); return defaultButtons; diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java index d6d8e7164..070f783ad 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java @@ -79,6 +79,17 @@ public BehaviorExamFormType(DataEntryFormContext ctx, Module owner) addClientDependency(ClientDependency.supplierFromPath("ehr/panel/ExamDataEntryPanel.js")); addClientDependency(ClientDependency.supplierFromPath("ehr/model/sources/ClinicalReportChild.js")); setJavascriptClass("EHR.panel.ExamDataEntryPanel"); + + // //Added: 12-18-2017 R.Blasa + setStoreCollectionClass("ONPRC_EHR.data.sources.BehaviorExamStoreCollection"); + addClientDependency(ClientDependency.fromPath("onprc_ehr/data/sources/BehaviorExamStoreCollection.js")); + + // //Added: 1-23-2018 R.Blasa +// Disable as temporary workaround to ticket Ticket 33579: Clinical Staff unsable to Create new Cases +// addClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageCasesWindow.js")); + + + } @Override @@ -86,6 +97,7 @@ protected List getButtonConfigs() { List ret = super.getButtonConfigs(); +// ret.add("OPEN_BEHAVIORCASE"); ret.add("OPENBEHAVIORCASE"); return ret; diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java index 5524575cf..5758bd470 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java @@ -62,6 +62,7 @@ public BiopsyFormType(DataEntryFormContext ctx, Module owner) s.addConfigSource("Encounter"); s.addConfigSource("Pathology"); s.addConfigSource("Biopsy"); + s.addConfigSource("Biopsy_Staff"); } addClientDependency(ClientDependency.supplierFromPath("ehr/model/sources/Pathology.js")); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java new file mode 100644 index 000000000..1c1ff8e3b --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.EHRService; +import org.labkey.api.ehr.dataentry.AbstractFormSection; +import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.ExtendedAnimalDetailsFormSection; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.SimpleFormPanelSection; +import org.labkey.api.ehr.dataentry.SimpleFormSection; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.ehr.dataentry.TaskForm; +import org.labkey.api.ehr.dataentry.TaskFormSection; +import org.labkey.api.ehr.security.EHRClinicalEntryPermission; +import org.labkey.api.module.Module; +import org.labkey.api.query.Queryable; +import org.labkey.api.view.template.ClientDependency; + +import java.util.Arrays; +import java.util.List; + +//Created: 1-31-2018 R.Blasa + +public class CagemateClinicalReportFormType extends TaskForm +{ + public static final String NAME = "Cagemate Soaps"; + + public CagemateClinicalReportFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "Cagemates Soaps", "Clinical", Arrays.asList( + new TaskFormSection(), + new AnimalDetailsFormSection(), + new SimpleGridPanel("study", "Clinical Remarks", "SOAPs") + + )); + + setStoreCollectionClass("EHR.data.ClinicalReportStoreCollection"); + addClientDependency(ClientDependency.fromPath("ehr/data/ClinicalReportStoreCollection.js")); + + setTemplateMode(AbstractFormSection.TEMPLATE_MODE.NO_ID); + setDisplayReviewRequired(true); + + for (FormSection s : this.getFormSections()) + { + s.addConfigSource("ClinicalDefaults"); + //Added 6-4-2015 Blasa + s.addConfigSource("ClinicalProcedures"); + } + + addClientDependency(ClientDependency.fromPath("ehr/model/sources/ClinicalDefaults.js")); + + + } + + + + @Override + protected boolean canInsert() + { + if (!getCtx().getContainer().hasPermission(getCtx().getUser(), EHRClinicalEntryPermission.class)) + return false; + + return super.canInsert(); + } + +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalReportFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalReportFormType.java index 1888d9404..c2ec73700 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalReportFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalReportFormType.java @@ -49,13 +49,13 @@ public class ClinicalReportFormType extends TaskForm public ClinicalReportFormType(DataEntryFormContext ctx, Module owner) { - super(ctx, owner, NAME, LABEL, "Clinical", Arrays.asList( + super(ctx, owner, NAME, LABEL, "Clinical", Arrays.asList( new NonStoreFormSection("Instructions", "Instructions", "ehr-examinstructionspanel", Arrays.asList(ClientDependency.supplierFromPath("ehr/panel/ExamInstructionsPanel.js"))), new TaskFormSection(), new ExtendedAnimalDetailsFormSection(), new SimpleFormPanelSection("study", "Clinical Remarks", "SOAP", false, EHRService.FORM_SECTION_LOCATION.Tabs), new ClinicalObservationsFormSection(EHRService.FORM_SECTION_LOCATION.Tabs), - new SimpleGridPanel("study", "encounters", "Procedures", EHRService.FORM_SECTION_LOCATION.Tabs), + new EncounterProcedureFormSection(EHRService.FORM_SECTION_LOCATION.Tabs), new WeightFormSection(EHRService.FORM_SECTION_LOCATION.Tabs), new DrugAdministrationFormSection(EHRService.FORM_SECTION_LOCATION.Tabs, DrugAdministrationFormSection.LABEL, ClientDependency.supplierFromPath("onprc_ehr/window/ONPRC_AddScheduledTreatmentWindow.js")), new TreatmentOrdersFormSection(EHRService.FORM_SECTION_LOCATION.Tabs), @@ -63,8 +63,7 @@ public ClinicalReportFormType(DataEntryFormContext ctx, Module owner) new SimpleGridPanel("ehr", "snomed_tags", "Diagnostic Codes", EHRService.FORM_SECTION_LOCATION.Tabs), //Added 5-23-2015 Blasa new SimpleGridPanel("study", "housing", "Housing Transfers",EHRService.FORM_SECTION_LOCATION.Tabs) - //Removed temporarily 7-2-2015 Blasa - // new SimpleGridPanel("study", "encounters", "TB Tests",EHRService.FORM_SECTION_LOCATION.Tabs) + )); @@ -74,10 +73,8 @@ public ClinicalReportFormType(DataEntryFormContext ctx, Module owner) for (FormSection s : this.getFormSections()) { s.addConfigSource("ClinicalDefaults"); - s.addConfigSource("ClinicalReport"); - - //Removed temporarily 7-2-2015 Blasa - // s.addConfigSource("TBProcedure"); +// s.addConfigSource("ClinicalReport"); + s.addConfigSource("ClinicalReport_ONPRC"); if (!s.getName().equals("Clinical Remarks")) s.addConfigSource("ClinicalReportChild"); @@ -103,8 +100,6 @@ public ClinicalReportFormType(DataEntryFormContext ctx, Module owner) addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/HousingDataEntryPanel.js")); setJavascriptClass("ONPRC_EHR.panel.HousingDataEntryPanel"); - //Removed temporarily 7-2-2015 Blasa - // addClientDependency(ClientDependency.fromFilePath("ehr/model/sources/TBProcedure.js")); } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java index acb9b02ca..8f06f3c4b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java @@ -63,7 +63,9 @@ public ClinicalRoundsFormType(DataEntryFormContext ctx, Module owner) for (FormSection s : this.getFormSections()) { s.addConfigSource("ClinicalDefaults"); - s.addConfigSource("ClinicalRounds"); + + //Modified: 10-5-2017 R.Blasa + s.addConfigSource("ClinicalRounds_ONPRC"); s.setTemplateMode(AbstractFormSection.TEMPLATE_MODE.NONE); } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java new file mode 100644 index 000000000..2de80b56e --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java @@ -0,0 +1,40 @@ + +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.EHRService; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.view.template.ClientDependency; + +//Created: 3-30-2017 R.Blasa +public class EncounterProcedureFormSection extends SimpleGridPanel +{ + public EncounterProcedureFormSection() + { + this(EHRService.FORM_SECTION_LOCATION.Body); + } + + public EncounterProcedureFormSection(EHRService.FORM_SECTION_LOCATION location) + { + super("study", "encounters", "Procedures", location); + //Added 3-30-2017 R.Blasa + addClientDependency(ClientDependency.fromPath("ehr/data/ClinicalEncountersClientStore.js")); + setClientStoreClass("EHR.data.ClinicalEncountersClientStore"); + + + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GeneticAncestryFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GeneticAncestryFormType.java new file mode 100644 index 000000000..6c45fb295 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GeneticAncestryFormType.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.ehr.dataentry.TaskFormSection; +import org.labkey.api.ehr.dataentry.UnsaveableTask; +import org.labkey.api.module.Module; + +import java.util.Arrays; + +/** + * User: bimber + * Date: 7/29/13 + * Time: 5:03 PM + */ +public class GeneticAncestryFormType extends UnsaveableTask +{ + public static final String NAME = "geneticAncestry"; + + public GeneticAncestryFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "Genetic Ancestry", "Colony Management", Arrays.asList( + new TaskFormSection(), + new AnimalDetailsFormSection(), + new SimpleGridPanel("study", "geneticAncestry", "Genetic Ancestry") + )); + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java index 027594fb9..5515935af 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java @@ -33,6 +33,9 @@ public GrossFindingsFormPanelSection() addClientDependency(ClientDependency.supplierFromPath("ehr/model/sources/EncounterChild.js")); addClientDependency(ClientDependency.supplierFromPath("ehr/window/EncounterAddRecordWindow.js")); + //Added: 5-17-2018 R.Blasa + addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/Gross_Finding.css")); + addConfigSource("Encounter"); addConfigSource("EncounterChild"); } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java new file mode 100644 index 000000000..d09d1242b --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.ehr.dataentry.TaskForm; +import org.labkey.api.ehr.dataentry.TaskFormSection; +import org.labkey.api.ehr.dataentry.UnsaveableTask; +import org.labkey.api.ehr.security.EHRClinicalEntryPermission; +import org.labkey.api.module.Module; +import org.labkey.api.view.template.ClientDependency; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +//Created: 4-5-2017 R.Blasa +public class NHPRProcessingFormType extends UnsaveableTask +{ + public static final String NAME = "NHPRProcess"; + + public NHPRProcessingFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "NHPR Processing", "Colony Management", Arrays.asList( + new TaskFormSection(), + new AnimalDetailsFormSection(), + new AssignmentFormSection(), + new SimpleGridPanel("study", "notes", "DCM Notes"), + new SimpleGridPanel("study", "flags", "Flags") + )); + + //Added 2-23-2016 R.Blasa + for (FormSection s : this.getFormSections()) + { + s.addConfigSource("ProjectAnimalConditions"); + } + + + //Added 5-26-2016 R.Blasa + addClientDependency(ClientDependency.fromPath("/onprc_ehr/model/sources/ProjectAnimalConditions.js")); + + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java index 307419aae..bc80b7d76 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java @@ -17,10 +17,12 @@ import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; import org.labkey.api.ehr.dataentry.SimpleGridPanel; import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.ehr.dataentry.UnsaveableTask; import org.labkey.api.module.Module; +import org.labkey.api.view.template.ClientDependency; import java.util.Arrays; @@ -40,5 +42,15 @@ public ParentageFormType(DataEntryFormContext ctx, Module owner) new AnimalDetailsFormSection(), new SimpleGridPanel("study", "parentage", "Parentage") )); + + //Added 12-27-2017 R.Blasa + for (FormSection s : this.getFormSections()) + { + s.addConfigSource("ParentageProperty"); + } + + + //Added 5-26-2016 R.Blasa + addClientDependency(ClientDependency.fromPath("/onprc_ehr/model/sources/Parentage_Properties.js")); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java index ce99ce277..8e8e4b24e 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java @@ -15,6 +15,8 @@ */ package org.labkey.onprc_ehr.dataentry; +import org.json.JSONObject; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; import org.labkey.api.view.template.ClientDependency; import java.util.ArrayList; @@ -38,6 +40,15 @@ public PathologyDiagnosesFormSection(String schemaName, String queryName, String setXtype("onprc_ehr-dragdropgridpanel"); } +// Added: 6-26-2017 R.Blasa Include tool bar at bottom grid + @Override + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { + JSONObject jsonObject = super.toJSON(ctx, includeFormElements); + jsonObject.put("topAndBottomButtons", true); + return jsonObject; + } + @Override public List getTbarMoreActionButtons() { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyTissuesFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyTissuesFormType.java index a4cc04103..4d6295e28 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyTissuesFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyTissuesFormType.java @@ -16,9 +16,11 @@ package org.labkey.onprc_ehr.dataentry; import org.labkey.api.ehr.EHRService; +import org.labkey.api.ehr.dataentry.AbstractFormSection; import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; import org.labkey.api.ehr.dataentry.DataEntryFormContext; import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.SimpleFormPanelSection; import org.labkey.api.ehr.dataentry.SimpleFormSection; import org.labkey.api.ehr.dataentry.TaskForm; import org.labkey.api.ehr.dataentry.TaskFormSection; @@ -51,7 +53,9 @@ public PathologyTissuesFormType(DataEntryFormContext ctx, Module owner) new DrugAdministrationFormSection(EHRService.FORM_SECTION_LOCATION.Tabs, DrugAdministrationFormSection.LABEL, ClientDependency.supplierFromPath("onprc_ehr/window/ONPRC_AddScheduledTreatmentWindow.js")), new SimpleFormSection("study", "tissue_samples", "Tissues/Weights", "onprc_ehr-dragdropgridpanel", EHRService.FORM_SECTION_LOCATION.Tabs), new TissueDistFormSection(), - new SimpleFormSection("study", "measurements", "Measurements", "onprc_ehr-dragdropgridpanel", EHRService.FORM_SECTION_LOCATION.Tabs) + +// Added: 6-26-2017 R.Blasa + new TissueMeasurementsFormSection() )); if (ctx.getContainer().getActiveModules().contains(ModuleLoader.getInstance().getModule("onprc_billing"))) @@ -63,6 +67,12 @@ public PathologyTissuesFormType(DataEntryFormContext ctx, Module owner) { s.addConfigSource("Pathology"); s.addConfigSource("Necropsy"); + s.addConfigSource("PathTissues"); + +// Added: 6-1-2017 R.Blasa + if (s instanceof SimpleFormSection ) + s.setTemplateMode(AbstractFormSection.TEMPLATE_MODE.NO_ID); + } addClientDependency(ClientDependency.supplierFromPath("ehr/model/sources/Pathology.js")); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ProcedureRequestBulkEditFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ProcedureRequestBulkEditFormType.java new file mode 100644 index 000000000..e7959f2ce --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ProcedureRequestBulkEditFormType.java @@ -0,0 +1,27 @@ + + +//Created: 10-9-2017 R.Blasa ASB Service Request (Procedures) + +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.dataentry.BulkEditFormType; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.module.Module; + +import java.util.Arrays; + +/** + + */ +public class ProcedureRequestBulkEditFormType extends BulkEditFormType +{ + public static final String NAME = "ProcedureBulkEdit"; + + public ProcedureRequestBulkEditFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "Procedure Requests", "Clinical", "lsid", Arrays.asList( + new EncounterProcedureFormSection() + )); + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SingleSurgeryFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SingleSurgeryFormType.java index 50ba175e1..e98836ab0 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SingleSurgeryFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SingleSurgeryFormType.java @@ -74,6 +74,12 @@ public SingleSurgeryFormType(DataEntryFormContext ctx, Module owner) { s.addConfigSource("Encounter"); s.addConfigSource("Surgery"); + + //Added: 9-6-2017 R.Blasa + s.addConfigSource("Surgery_Blood"); + + //Added: 10-13-2017 R.Blasa + s.addConfigSource("Biopsy_Staff"); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgeryFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgeryFormType.java index 9eb28fb10..d53b31f0d 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgeryFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgeryFormType.java @@ -74,6 +74,12 @@ public SurgeryFormType(DataEntryFormContext ctx, Module owner) { s.addConfigSource("Encounter"); s.addConfigSource("Surgery"); + + //Added: 9-6-2017 R.Blasa + s.addConfigSource("Surgery_Blood"); + + //Added: 10-13-2017 R.Blasa + s.addConfigSource("Biopsy_Staff"); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgicalRoundsFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgicalRoundsFormType.java index 9695aa954..7bd3cd163 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgicalRoundsFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/SurgicalRoundsFormType.java @@ -26,6 +26,10 @@ import org.labkey.api.security.SecurityManager; import org.labkey.api.security.UserPrincipal; import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.Group; +import org.labkey.api.security.permissions.AdminPermission; import java.util.Arrays; @@ -59,6 +63,19 @@ public SurgicalRoundsFormType(DataEntryFormContext ctx, Module owner) setDisplayReviewRequired(true); } + //Added: 7-26-2018 R.Blasa + @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "Surgery Research", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + return super.isVisible(); + } + + @Override protected boolean canInsert() { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueDistFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueDistFormSection.java index 26c25fb90..95afd3874 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueDistFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueDistFormSection.java @@ -15,8 +15,10 @@ */ package org.labkey.onprc_ehr.dataentry; +import org.json.JSONObject; import org.labkey.api.ehr.EHRService; import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; import org.labkey.api.view.template.ClientDependency; import java.util.List; @@ -36,6 +38,14 @@ public TissueDistFormSection() addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/window/CopyTissuesWindow.js")); addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/grid/DragDropGridPanel.js")); } +// Added: 6-26-2017 R.Blasa Include tool bar at bottom grid + @Override + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { + JSONObject jsonObject = super.toJSON(ctx, includeFormElements); + jsonObject.put("topAndBottomButtons", true); + return jsonObject; + } @Override public List getTbarMoreActionButtons() diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java new file mode 100644 index 000000000..3130cd15a --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.json.JSONObject; +import org.labkey.api.ehr.EHRService; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.view.template.ClientDependency; + +//Created: 6-26-2017 R.Blasa + +public class TissueMeasurementsFormSection extends SimpleGridPanel +{ + public TissueMeasurementsFormSection() + { + super("study", "measurements", "Measurements"); + setLocation(EHRService.FORM_SECTION_LOCATION.Tabs); + setXtype("onprc_ehr-dragdropgridpanel"); + addClientDependency(ClientDependency.fromPath("onprc_ehr/grid/DragDropGridPanel.js")); + } + + // Added: 6-26-2017 R.Blasa Include tool bar at bottom grid + @Override + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { + JSONObject jsonObject = super.toJSON(ctx, includeFormElements); + jsonObject.put("topAndBottomButtons", true); + return jsonObject; + } + +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java new file mode 100644 index 000000000..ed5e07633 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.json.JSONObject; +import org.labkey.api.ehr.*; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; +import org.labkey.api.view.template.ClientDependency; + + +//Created: 6-26-2017 R.Blasa + +public class TissueWeightsFormSection extends SimpleGridPanel +{ + public TissueWeightsFormSection() + { + super("study", "tissue_samples", "Tissues/Weights"); + setLocation(EHRService.FORM_SECTION_LOCATION.Tabs); + setXtype("onprc_ehr-dragdropgridpanel"); + addClientDependency(ClientDependency.fromPath("onprc_ehr/grid/DragDropGridPanel.js")); + } + + // Added: 6-26-2017 R.Blasa Include tool bar at bottom grid + @Override + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { + JSONObject jsonObject = super.toJSON(ctx, includeFormElements); + jsonObject.put("topAndBottomButtons", true); + return jsonObject; + } + +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/WeightFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/WeightFormType.java index 17ca8f841..05323d736 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/WeightFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/WeightFormType.java @@ -15,6 +15,7 @@ */ package org.labkey.onprc_ehr.dataentry; + import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; import org.labkey.api.ehr.dataentry.DataEntryFormContext; import org.labkey.api.ehr.dataentry.FormSection; @@ -23,10 +24,15 @@ import org.labkey.api.ehr.dataentry.WeightFormSection; import org.labkey.api.ehr.dataentry.DrugAdministrationFormSection; import org.labkey.api.module.Module; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.view.template.ClientDependency; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.Group; +import org.labkey.security.xml.GroupEnumType; import java.util.Arrays; + /** * User: bimber * Date: 7/29/13 @@ -54,4 +60,15 @@ public WeightFormType(DataEntryFormContext ctx, Module owner) s.addConfigSource("Weight"); } } +//Added: 5-16-2018 R.Blasa + @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "Research Clinical Entry", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + return super.isVisible(); + } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveTreatmentsXDemographicsProvider.java b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveTreatmentsXDemographicsProvider.java new file mode 100644 index 000000000..17dff8712 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveTreatmentsXDemographicsProvider.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.demographics; + +import org.labkey.api.data.CompareType; +import org.labkey.api.data.SimpleFilter; +import org.labkey.api.ehr.demographics.AbstractListDemographicsProvider; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; +import org.apache.commons.lang3.time.DateUtils; + +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.Calendar; + + +//Created: 4-7-2017 R.Blasa +public class ActiveTreatmentsXDemographicsProvider extends AbstractListDemographicsProvider +{ + public ActiveTreatmentsXDemographicsProvider(Module module) + { + super(module, "study", "Treatment Orders", "activeTreatments"); + _supportsQCState = false; + } + + protected Set getFieldKeys() + { + Set keys = new HashSet(); + keys.add(FieldKey.fromString("lsid")); + keys.add(FieldKey.fromString("Id")); + keys.add(FieldKey.fromString("code")); + keys.add(FieldKey.fromString("code/meaning")); + keys.add(FieldKey.fromString("date")); + keys.add(FieldKey.fromString("enddate")); + keys.add(FieldKey.fromString("performedby")); + keys.add(FieldKey.fromString("route")); + + keys.add(FieldKey.fromString("dosage")); + keys.add(FieldKey.fromString("dosage_units")); + keys.add(FieldKey.fromString("amount")); + keys.add(FieldKey.fromString("amount_units")); + keys.add(FieldKey.fromString("concentration")); + keys.add(FieldKey.fromString("concentration_units")); + keys.add(FieldKey.fromString("volume")); + keys.add(FieldKey.fromString("vol_units")); + keys.add(FieldKey.fromString("amountAndVolume")); + + keys.add(FieldKey.fromString("remark")); + keys.add(FieldKey.fromString("frequency")); + keys.add(FieldKey.fromString("frequency/meaning")); + + keys.add(FieldKey.fromString("amountWithUnits")); + keys.add(FieldKey.fromString("category")); + + return keys; + } + + @Override + public Collection getKeysToTest() + { + //for now, simply skip the whole provider. because different records can be active from day to day, this makes validation tricky + Set keys = new HashSet<>(super.getKeysToTest()); + keys.remove(_propName); + + return keys; + } + + @Override + protected SimpleFilter getFilter(Collection ids) + { Date roundedMax = new Date(); + roundedMax = DateUtils.truncate(roundedMax, Calendar.DATE); + + SimpleFilter filter = super.getFilter(ids); + filter.addCondition(FieldKey.fromString("enddateTimeCoalesced"),roundedMax, CompareType.GTE); + filter.addCondition(FieldKey.fromString("category"), "Husbandry", CompareType.NEQ_OR_NULL); + + return filter; + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/AssignedVetDemographicsProvider.java b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/AssignedVetDemographicsProvider.java index 5c63b71d6..10ac21f35 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/AssignedVetDemographicsProvider.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/AssignedVetDemographicsProvider.java @@ -63,6 +63,8 @@ public Collection getKeysToTest() @Override public boolean requiresRecalc(String schema, String query) { - return "study".equalsIgnoreCase(schema) && ("housing".equalsIgnoreCase(query) || "assignment".equalsIgnoreCase(query) || "cases".equalsIgnoreCase(query)); + return "study".equalsIgnoreCase(schema) && ("Demographics".equalsIgnoreCase(query) || "housing".equalsIgnoreCase(query) || "assignment".equalsIgnoreCase(query) || "cases".equalsIgnoreCase(query)) || + ("onprc_ehr".equalsIgnoreCase(schema) && "vet_assignment".equalsIgnoreCase(query)); } } + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/FosterChildDemographicsProvider.java b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/FosterChildDemographicsProvider.java index 8eea6c269..854c06421 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/FosterChildDemographicsProvider.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/FosterChildDemographicsProvider.java @@ -15,6 +15,7 @@ */ package org.labkey.onprc_ehr.demographics; +import org.labkey.api.data.Sort; import org.labkey.api.ehr.demographics.AbstractListDemographicsProvider; import org.labkey.api.module.Module; import org.labkey.api.query.FieldKey; @@ -45,12 +46,18 @@ protected Collection getFieldKeys() return keys; } + @Override + protected Sort getSort() + { + + return new Sort("-date"); + } + @Override public boolean requiresRecalc(String schema, String query) { - return ("study".equalsIgnoreCase(schema) && "Parentage".equalsIgnoreCase(query)) || - ("study".equalsIgnoreCase(schema) && "Birth".equalsIgnoreCase(query)) || - ("study".equalsIgnoreCase(schema) && "Demographics".equalsIgnoreCase(query)); + return ("study".equalsIgnoreCase(schema) && "Parentage".equalsIgnoreCase(query)) ; + } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/GeneticAncestryDemographicsProvider.java b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/GeneticAncestryDemographicsProvider.java new file mode 100644 index 000000000..40e503473 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/GeneticAncestryDemographicsProvider.java @@ -0,0 +1,41 @@ +package org.labkey.onprc_ehr.demographics; + +import org.labkey.api.ehr.demographics.AbstractDemographicsProvider; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by bimber on 3/23/2017. + */ +public class GeneticAncestryDemographicsProvider extends AbstractDemographicsProvider +{ + public GeneticAncestryDemographicsProvider(Module module) + { + super(module, "study", "demographicsGeneticAncestry"); + _supportsQCState = false; + } + + @Override + public String getName() + { + return "Genetic Ancestry"; + } + + protected Collection getFieldKeys() + { + Set keys = new HashSet<>(); + keys.add(FieldKey.fromString("geneticAncestry")); + + return keys; + } + + @Override + public boolean requiresRecalc(String schema, String query) + { + return "study".equalsIgnoreCase(schema) && ("geneticAncestry".equalsIgnoreCase(query) || "Genetic Ancestry".equalsIgnoreCase(query)); + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCClinicalRemarksDataSource.java b/onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCClinicalRemarksDataSource.java new file mode 100644 index 000000000..56307b142 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCClinicalRemarksDataSource.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.history; + +import org.labkey.api.data.Container; +import org.labkey.api.data.Results; +import org.labkey.api.ehr.history.AbstractDataSource; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; +import org.labkey.api.util.PageFlowUtil; + +import java.sql.SQLException; +import java.util.Set; + +/** + * User: bimber + * Date: 2/17/13 + * Time: 4:52 PM + */ +public class ONPRCClinicalRemarksDataSource extends AbstractDataSource +{ + public static final String REPLACED_SOAP = "Replaced SOAP"; + public static final String REPLACEMENT_SOAP = "Replacement SOAP"; + + public ONPRCClinicalRemarksDataSource(Module module) + { + super("study", "Clinical Remarks", "Clinical Remark", "Clinical", module); + setShowTime(true); + } + + @Override + protected String getCategoryText(Results rs) throws SQLException + { + String category = rs.getString("category"); + return (category == null || REPLACED_SOAP.equals(category) || REPLACEMENT_SOAP.equals(category) ? "Clinical" : category) + " Remark"; + } + + + @Override + protected String getPrimaryGroup(Results rs) throws SQLException + { + String category = rs.getString("category"); + return (category == null ? "Clinical" : category); + } + + @Override + protected String getHtml(Container c, Results rs, boolean redacted) throws SQLException + { + StringBuilder sb = new StringBuilder(); + sb.append(""); + + String category = rs.getString(FieldKey.fromString("category")); + + //this is a mechanism to allow individual notes to be replaced, yet remain in the record + if (REPLACED_SOAP.equals(category)) + { + return null; + } + + if (!redacted && rs.getObject(FieldKey.fromString("performedby")) != null) + { + String label; + if ("Replacement SOAP".equals(category)) + { + label = "Amended By"; + } + else + { + label = "Entered By"; + } + + appendNote(rs, "performedby", "" + label + "", sb); + } + + appendNote(rs, "hx", "Hx", sb); + appendNote(rs, "so", "S/O", sb); + appendNote(rs, "s", "S", sb); + appendNote(rs, "o", "O", sb); + appendNote(rs, "a", "A", sb); + appendNote(rs, "p", "P", sb); + appendNote(rs, "p2", "P2", sb); + appendNote(rs, "CEG_Plan", "CEG Plan", sb); + appendNote(rs, "remark", "Other Remark", sb); + + sb.append("
"); + + return sb.toString(); + } + + @Override + protected Set getColumnNames() + { + return PageFlowUtil.set("Id", "date", "enddate", "category", "hx", "so", "s", "o", "a", "p", "p2", "remark","CEG_Plan", "performedby"); + } + + private void appendNote(Results rs, String field, String label, StringBuilder sb) throws SQLException + { + if (rs.hasColumn(FieldKey.fromString(field)) && rs.getObject(FieldKey.fromString(field)) != null) + { + sb.append("" + label + ":"); + sb.append(rs.getString(FieldKey.fromString(field))); + sb.append(""); + } + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCiStatLabworkType.java b/onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCiStatLabworkType.java new file mode 100644 index 000000000..8175d5bd2 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/history/ONPRCiStatLabworkType.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.history; + +import org.labkey.api.ehr.history.SortingLabworkType; +import org.labkey.api.module.Module; + +/** + * User: bimber + * Date: 3/19/13 + * Time: 11:02 PM + */ +public class ONPRCiStatLabworkType extends SortingLabworkType +{ + public ONPRCiStatLabworkType(Module module) + { + super("iStat", "study", "iStatRefRange", "iStat", module); + _normalRangeField = "range"; + _normalRangeStatusField = "status"; + } + + @Override + public boolean showPerformedBy() + { + return false; + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BSUNotesNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BSUNotesNotification.java new file mode 100644 index 000000000..f1b934277 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BSUNotesNotification.java @@ -0,0 +1,59 @@ +package org.labkey.onprc_ehr.notification; + +import org.labkey.api.data.Container; +import org.labkey.api.module.Module; +import org.labkey.api.security.User; + +import java.util.Date; + +/** + * Created by kollil on 5/12/2017. + */ + +public class BSUNotesNotification extends ColonyAlertsNotification +{ + public BSUNotesNotification(Module owner) + { + super(owner); + } + + @Override + public String getName() + { + return "BSU Notes Notification"; + } + + @Override + public String getEmailSubject(Container c) + { + return "BSU Notes Alerts: " + getDateTimeFormat(c).format(new Date()); + } + + @Override + public String getCronString() + { + return "0 0 5 * * ?"; + } + + @Override + public String getScheduleDescription() + { + return "every day at 5:00AM"; + } + + @Override + public String getDescription() + { + return "The report is designed to send BSU Notes alerts on the day indicated by the action date!"; + } + + @Override + public String getMessageBodyHTML(Container c, User u) + { + StringBuilder msg = new StringBuilder(); + + bsuNotesAlert(c, u, msg); + + return msg.toString(); + } +} \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java index 1f1dfacbb..b323ee611 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java @@ -114,17 +114,17 @@ public String getMessageBodyHTML(Container c, User u) return msg.toString(); } +// Modified: 9-7-2018 R.Blasa private void behaviorCaseSummary(Container c, User u, final StringBuilder msg) { - TableInfo ti = getStudySchema(c, u).getTable("cases"); + TableInfo ti = getStudySchema(c, u).getTable("mostRecentObservationsBehavior"); SimpleFilter filter = new SimpleFilter(FieldKey.fromString("isActive"), true); - filter.addCondition(FieldKey.fromString("category"), "Behavior"); TableSelector ts = new TableSelector(ti, PageFlowUtil.set("Id"), filter, null); long total = ts.getRowCount(); msg.append("Behavior Cases:

"); msg.append("There are " + total + " active behavior cases (this does not include cases closed for review). "); - String url = getExecuteQueryUrl(c, "study", "cases", "Open Behavior Cases") + "&query.isActive~eq=true"; + String url = getExecuteQueryUrl(c, "study", "mostRecentObservationsBehavior", "Open Behavior Case") + "&query.isActive~eq=true"; msg.append("Click here to view them"); msg.append("


"); } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BirthHousingMismatchNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BirthHousingMismatchNotification.java new file mode 100644 index 000000000..394da9fa1 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BirthHousingMismatchNotification.java @@ -0,0 +1,60 @@ +package org.labkey.onprc_ehr.notification; + +import org.labkey.api.data.Container; +import org.labkey.api.module.Module; +import org.labkey.api.security.User; + +import java.util.Date; + +// Created: 8-7-2018 R.Blasa +public class BirthHousingMismatchNotification extends ColonyAlertsNotification +{ + public BirthHousingMismatchNotification(Module owner) + { + super(owner); + } + + @Override + public String getName() + { + return "Birth Initial Housing Locations Discrepancies Notification"; + } + + @Override + public String getEmailSubject(Container c) + { + return "Discrepancies between Birth and Initial Housing Locations Alerts: " + getDateTimeFormat(c).format(new Date()); + } + + @Override + public String getCronString() + { + return "0 0 6 * * ?"; + } + + @Override + public String getScheduleDescription() + { + return "every day at 6:00AM"; + } + + @Override + public String getDescription() + { + return "The report is designed to provide a daily summary of discrepancies between Birth and Initial Housing Locations."; + } + + @Override + public String getMessageBodyHTML(Container c, User u) + { + StringBuilder msg = new StringBuilder(); + + ValidateBiirthHousingHistory(c, u, msg); + + return msg.toString(); + } +} + + + + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index 7f72bb35e..17e5cd8f4 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -143,6 +143,7 @@ public String getMessageBodyHTML(final Container c, User u) //misc demographicsWithoutGender(c, u, msg); + getGeographicOriginConflicts(c, u, msg); incompleteBirthRecords(c, u, msg); birthRecordsWithoutDemographics(c, u, msg); @@ -603,6 +604,9 @@ protected void infantsNotAssignedToDamSPF(final Container c, User u, final Strin SimpleFilter filter = new SimpleFilter(FieldKey.fromString("matchesDamStatus"), false, CompareType.EQUAL); filter.addCondition(FieldKey.fromString("dam"), null, CompareType.NONBLANK); +// Added: 6-21-2017 R.Blasa + filter.addCondition(FieldKey.fromString("dam"), "", CompareType.NEQ); + Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1 * duration); filter.addCondition(FieldKey.fromString("birth"), cal.getTime(), CompareType.DATE_GTE); @@ -689,7 +693,7 @@ protected void duplicateCases(final Container c, User u, final StringBuilder msg long count = ts.getRowCount(); if (count > 0) { - msg.append("WARNING: There are " + count + " animals with multiple active cases of the same category. One of the duplicates should be closed or set for review
\n"); + msg.append("WARNING: There are " + count + " animals with multiple active cases of the same category. One of the duplicates should be closed or set for review
\n"); msg.append("

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


\n\n"); } @@ -702,8 +706,6 @@ protected void recordsEnteredMoreThan7DaysAfter(final Container c, User u, final { int offset = 7; - - } @@ -960,6 +962,68 @@ protected void protocolsExpiringSoon(final Container c, User u, final StringBuil } } + /** + * Kollil : Find the pregnant NHPs whose gestation time is past 30 days + */ + protected void checkPregnantGestation(final Container c, User u, final StringBuilder msg) + { + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("thirty_days_pastGestation_date"), new Date(), CompareType.DATE_LTE); + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("pregnancyGestationOverdue"), filter, null); + long count = ts.getRowCount(); + if (count > 0) + { + msg.append("WARNING: There are " + count + " pregnant animals 30 days past the gestation period.
\n"); + msg.append("

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


\n\n"); + } + else + { + msg.append("WARNING: There are no pregnant animals 30 days past the gestation period.
\n"); + } + } + + /** + * Kollil, 5/12/2017 : Send DCM Notes notification on the action date + */ + protected void dcmNotesAlert(final Container c, User u, final StringBuilder msg) + { + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("actiondate"), new Date(), CompareType.DATE_EQUAL); + filter.addCondition(FieldKey.fromString("category"), "Notes Pertaining to DAR", CompareType.EQUAL); + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("notes"), filter, null); + long count = ts.getRowCount(); + if (count > 0) + { + msg.append("WARNING: There are " + count + " DCM action items.
\n"); + msg.append("

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


\n\n"); + } + else + { + msg.append("WARNING: There are no DCM action items!
\n"); + } + } + + /** + * Kollil, 5/12/2017 : Send BSU Notes notification on the action date + */ + protected void bsuNotesAlert(final Container c, User u, final StringBuilder msg) + { + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("actiondate"), new Date(), CompareType.DATE_EQUAL); + filter.addCondition(FieldKey.fromString("category"), "BSU Notes", CompareType.EQUAL); + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("notes"), filter, null); + long count = ts.getRowCount(); + if (count > 0) + { + msg.append("WARNING: There are " + count + " BSU action items.
\n"); + msg.append("

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


\n\n"); + } + else + { + msg.append("WARNING: There are no BSU action items!
\n"); + } + } + /** * we find protocols over the animal limit */ @@ -1006,6 +1070,24 @@ protected void assignmentsNotAllowed(final Container c, User u, final StringBuil } } + //Added: 8-7-2018 R.Blasa + protected void ValidateBiirthHousingHistory(final Container c, User u, final StringBuilder msg) + { + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("BirthInitialHousingMismatch"), null, null); + long count = ts.getRowCount(); + if (count > 0) + { + msg.append("WARNING: There are " + count + " several Birth ids having mismatched initial locations
\n"); + msg.append("

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


\n\n"); + } + else + { + msg.append("WARNING: There are no Birth Initial Housing mismtached locations to report.
\n"); + } + } + + protected void overlappingProtocolCounts(final Container c, User u, final StringBuilder msg) { TableSelector ts = new TableSelector(getEHRSchema(c, u).getTable("protocolGroupsOverlapping")); @@ -1021,6 +1103,19 @@ protected void overlappingProtocolCounts(final Container c, User u, final String } } + protected void getGeographicOriginConflicts(final Container c, User u, final StringBuilder msg) + { + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("geographicOriginConflicts")); + long count = ts.getRowCount(); + + if (count > 0) + { + msg.append("WARNING: There are " + count + " animals where the demographics table value for geographic origin conflicts with genetic ancestry.
\n"); + msg.append("

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


\n\n"); + } + } + /** * we find all animals that died in the past 90 days where there isnt a weight within 7 days of death: */ diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DCMNotesNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DCMNotesNotification.java new file mode 100644 index 000000000..aeaea239e --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DCMNotesNotification.java @@ -0,0 +1,58 @@ +package org.labkey.onprc_ehr.notification; + +import org.labkey.api.data.Container; +import org.labkey.api.module.Module; +import org.labkey.api.security.User; + +import java.util.Date; + +/** + * Created by kollil on 5/12/2017. + */ +public class DCMNotesNotification extends ColonyAlertsNotification +{ + public DCMNotesNotification(Module owner) + { + super(owner); + } + + @Override + public String getName() + { + return "DCM Notes Notification"; + } + + @Override + public String getEmailSubject(Container c) + { + return "DCM Notes Alerts: " + getDateTimeFormat(c).format(new Date()); + } + + @Override + public String getCronString() + { + return "0 0 5 * * ?"; + } + + @Override + public String getScheduleDescription() + { + return "every day at 5:00AM"; + } + + @Override + public String getDescription() + { + return "The report is designed to send DCM Notes alerts on the day indicated by the action date!"; + } + + @Override + public String getMessageBodyHTML(Container c, User u) + { + StringBuilder msg = new StringBuilder(); + + dcmNotesAlert(c, u, msg); + + return msg.toString(); + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java new file mode 100644 index 000000000..87ff4d4e7 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.notification; + +import org.apache.commons.lang3.time.DateUtils; +import org.json.JSONObject; +import org.labkey.api.data.CompareType; +import org.labkey.api.data.Container; +import org.labkey.api.data.SQLFragment; +import org.labkey.api.data.Selector; +import org.labkey.api.data.SimpleFilter; +import org.labkey.api.data.Sort; +import org.labkey.api.data.SqlSelector; +import org.labkey.api.data.TableInfo; +import org.labkey.api.data.TableSelector; +import org.labkey.api.ehr.notification.AbstractEHRNotification; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; +import org.labkey.api.query.QueryDefinition; +import org.labkey.api.query.QueryException; +import org.labkey.api.query.QueryService; +import org.labkey.api.query.UserSchema; +import org.labkey.api.security.User; +import org.labkey.api.util.DateUtil; +import org.labkey.api.util.PageFlowUtil; +import org.labkey.api.data.ColumnInfo; +import org.labkey.api.data.Results; +import org.labkey.api.data.ResultsImpl; +import org.apache.commons.lang3.StringUtils; + + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.text.ParseException; + +//Created: 3-8-2017 R.Blasa +public class InfantsBornAssignedNotification extends AbstractEHRNotification +{ + public InfantsBornAssignedNotification(Module owner) + { + super(owner); + } + + @Override + public String getName() + { + return "Infants Born to Assigned Animals Notification"; + } + + @Override + public String getEmailSubject(Container c) + { + return "Infants Born To Assigned Animals Alerts: " + getDateTimeFormat(c).format(new Date()); + } + + @Override + public String getCronString() + { + return "0 0 7 * * ?"; + } + + @Override + public String getScheduleDescription() + { + return "every day at 7:00AM"; + } + + @Override + public String getDescription() + { + return "The report is designed to warn users of infants that are born to Assigned Animals"; + } + + @Override + public String getMessageBodyHTML(Container c, User u) + { + Map saved = getSavedValues(c); + Map toSave = new HashMap(); + + StringBuilder msg = new StringBuilder(); + + AssignedInfantprocess(c, u, msg); + + return msg.toString(); + } + + private void AssignedInfantprocess(Container c, User u, final StringBuilder msg) + { + + Calendar date = Calendar.getInstance(); + date.setTime(new Date()); + date.add(Calendar.DATE, -45); + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("date"), date.getTime(), CompareType.DATE_GTE); //birth date + + + Sort sort = new Sort("-date"); + + TableInfo ti = getStudySchema(c, u).getTable("InfantsBorntoAssigned"); + List colKeys = new ArrayList<>(); + colKeys.add(FieldKey.fromString(getStudy(c).getSubjectColumnName())); + colKeys.add(FieldKey.fromString("Id")); + colKeys.add(FieldKey.fromString("date")); + colKeys.add(FieldKey.fromString("dam")); + colKeys.add(FieldKey.fromString("ProjectName")); + + final Map columns = QueryService.get().getColumns(ti, colKeys); + + TableSelector ts = new TableSelector(ti, columns.values(), filter, sort); + long total = ts.getRowCount(); + if (total == 0) + { + msg.append("There are no Expiring Obese Flag for today.\n"); + } + else + { + //Create header information on this report + msg.append(""); + msg.append("\n"); + + + ts.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet rs) throws SQLException + { + Results results = new ResultsImpl(rs, columns); + String Ids = results.getString(FieldKey.fromString("Id")); + Date datess = results.getDate(FieldKey.fromString("date")); + String dams = results.getString(FieldKey.fromString("dam")); + String projectname = results.getString(FieldKey.fromString("ProjectName")); + + msg.append("\n"); + + } + }); + + msg.append("
Monkey IDDateProject NameDam
" + Ids + "" + getDateTimeFormat(c).format(datess) + "" + projectname + "" + dams + "
\n"); + + } + } + + + + + + + +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/PregnantNHPsGestationAlert.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/PregnantNHPsGestationAlert.java new file mode 100644 index 000000000..19d4e14b6 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/PregnantNHPsGestationAlert.java @@ -0,0 +1,62 @@ +package org.labkey.onprc_ehr.notification; + +import org.labkey.api.data.Container; +import org.labkey.api.module.Module; +import org.labkey.api.security.User; + +import java.util.Date; + +/** + * Created by kollil + */ +public class PregnantNHPsGestationAlert extends ColonyAlertsNotification +{ + public PregnantNHPsGestationAlert(Module owner) + { + super(owner); + } + + @Override + public String getName() + { + return "Pregnant NHPs Gestation Notification"; + } + + @Override + public String getEmailSubject(Container c) + { + return "Pregnant Animal Alerts: " + getDateTimeFormat(c).format(new Date()); + } + + @Override + public String getCronString() + { + return "0 0 5 * * ?"; + } + + @Override + public String getScheduleDescription() + { + return "every day at 5:00AM"; + } + + @Override + public String getDescription() + { + return "The report is designed to provide a daily summary of pregnant NHPs past 30 days of gestation for the colony!"; + } + + @Override + public String getMessageBodyHTML(Container c, User u) + { + StringBuilder msg = new StringBuilder(); + + checkPregnantGestation(c, u, msg); + + return msg.toString(); + } +} + + + + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/RoutineClinicalTestsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/RoutineClinicalTestsNotification.java index cf9741337..db046437b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/RoutineClinicalTestsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/RoutineClinicalTestsNotification.java @@ -260,7 +260,7 @@ protected void getAnimalsNotWeightedInPast60Days(StringBuilder msg, Container c, msg.append("Weights:

\n"); SimpleFilter filter = new SimpleFilter(FieldKey.fromString("calculated_status"), "Alive"); - filter.addCondition(FieldKey.fromString("Id/MostRecentWeight/DaysSinceWeight"), 60, CompareType.GT); + filter.addCondition(FieldKey.fromString("Id/MostRecentWeight/DaysSinceWeight"), 45, CompareType.GT); filter.addCondition(FieldKey.fromString("Id/curLocation/Room/housingType/value"), "Cage Location", CompareType.EQUAL); TableInfo ti = getStudySchema(c, u).getTable("demographics"); @@ -272,8 +272,8 @@ protected void getAnimalsNotWeightedInPast60Days(StringBuilder msg, Container c, if (count > 0) { - msg.append("WARNING: There are " + count + " animals in cage locations and have not been weighed in the past 60 days: "); - String url = getExecuteQueryUrl(c, "study", "Demographics", "By Location") + "&query.Id/MostRecentWeight/DaysSinceWeight~gt=60&query.calculated_status~eq=Alive&query.Id/curLocation/Room/housingType/value~eq=Cage Location"; + msg.append("WARNING: There are " + count + " animals in cage locations and have not been weighed in the past 45 days: "); + String url = getExecuteQueryUrl(c, "study", "Demographics", "By Location") + "&query.Id/MostRecentWeight/DaysSinceWeight~gt=45&query.calculated_status~eq=Alive&query.Id/curLocation/Room/housingType/value~eq=Cage Location"; msg.append("Click here to view them.

\n"); msg.append("Summary by area:
\n"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java index 5d8bde536..3f16bea72 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java @@ -60,7 +60,7 @@ public String getName() @Override public String getDescription() { - return "This runs every day at 9AM, 1PM, 5PM if there are treatments scheduled that have not yet been marked complete"; + return "This runs every day at 9AM, 3PM if there are treatments scheduled that have not yet been marked complete"; } @Override @@ -70,12 +70,12 @@ public String getEmailSubject(Container c) } @Override - public String getCronString() {return "0 0 9,13,17 * * ?";} + public String getCronString() {return "0 0 9,15 * * ?";} @Override public String getScheduleDescription() { - return "daily at 9AM,1PM, 5PM"; + return "daily at 9AM,3PM"; } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/UnoccupiedRoomsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/UnoccupiedRoomsNotification.java index 3e41bf290..a2b728342 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/UnoccupiedRoomsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/UnoccupiedRoomsNotification.java @@ -15,6 +15,7 @@ */ package org.labkey.onprc_ehr.notification; +import org.apache.commons.lang3.StringUtils; import org.labkey.api.data.AbstractTableInfo; import org.labkey.api.data.CompareType; import org.labkey.api.data.Container; @@ -23,15 +24,28 @@ import org.labkey.api.data.Sort; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; +import org.labkey.api.ehr.EHRService; import org.labkey.api.ldk.LDKService; import org.labkey.api.module.Module; import org.labkey.api.query.FieldKey; +import org.labkey.api.query.QueryService; +import org.labkey.api.query.UserSchema; import org.labkey.api.security.User; +import org.labkey.api.settings.AppProps; import org.labkey.api.util.PageFlowUtil; +import org.labkey.api.data.ColumnInfo; +import org.labkey.api.data.Results; +import org.labkey.api.data.ResultsImpl; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; import java.util.Date; +import java.util.Map; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; /** * User: bimber @@ -82,31 +96,38 @@ public String getMessageBodyHTML(Container c, User u) unoccupiedNHPRooms(c, u, msg); - + unoccupiedSLARooms(c, u, msg); return msg.toString(); } + private void unoccupiedNHPRooms(Container c, User u, final StringBuilder msg) { TableInfo ti = getEHRLookupsSchema(c, u).getTable("rooms", null , true, true); assert ti instanceof AbstractTableInfo; - LDKService.get().applyNaturalSort((AbstractTableInfo)ti, "room"); + LDKService.get().applyNaturalSort((AbstractTableInfo) ti, "room"); + + //NHP Locations SimpleFilter filter = new SimpleFilter(FieldKey.fromString("utilization/TotalAnimals"), 0); + + //NHP Location filters filter.addCondition(FieldKey.fromString("housingType/value"), "Rodent Location", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("housingType/value"), "Off Campus", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("datedisabled"), null, CompareType.ISBLANK); filter.addCondition(FieldKey.fromString("building"), null, CompareType.NONBLANK); Sort sort = new Sort("building,room"); + //NHP unoccupied locations TableSelector ts = new TableSelector(ti, PageFlowUtil.set("room", "building", "room_sortValue"), filter, sort); if (ts.getRowCount() == 0) { - msg.append("There are no empty rooms"); + msg.append("There are no empty NHP rooms"); } else { + msg.append("Unoccupied NHP Locations:
\n"); msg.append(""); msg.append(""); @@ -122,4 +143,62 @@ public void exec(ResultSet rs) throws SQLException msg.append("
BuildingRoom
"); } } + + private void unoccupiedSLARooms(Container c, User u, final StringBuilder msg) + { + /***************************** + //SLA Unoccupied Locations// + ******************************/ + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("SLAOccupiedLocations"); + + + //SLA Locations + + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Cage_Count"),null, CompareType.ISBLANK); + + //SLA Location filters + filter.addCondition(FieldKey.fromString("building"), null, CompareType.NONBLANK); + + + //SLA unoccupied locations + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("room")); + columns.add(FieldKey.fromString("building")); + columns.add(FieldKey.fromString("Date")); + columns.add(FieldKey.fromString("Animal_Count")); + columns.add(FieldKey.fromString("Cage_Count")); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts = new TableSelector(ti, colMap.values(), filter, new Sort("building,room")); + + + String url = getExecuteQueryUrl(c, "sla", "SLAOccupiedLocations", null) ; + long total = ts.getRowCount(); + + if (total == 0) + { + msg.append("There are no empty SLA rooms"); + } + else + { + msg.append("


Unoccupied SLA Locations:

\n"); + msg.append(""); + msg.append(""); + + ts.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet object) throws SQLException + + { + Results rs = new ResultsImpl(object, colMap); + msg.append(""); + } + }); + + msg.append("
BuildingRoom
" + (rs.getString("building") == null ? "" : rs.getString("building")) + "" + rs.getString("room") + "
"); + + + } + } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java index 3e17cead0..8000f7958 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java @@ -15,7 +15,6 @@ */ package org.labkey.onprc_ehr.query; -import org.apache.commons.beanutils.ConversionException; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.jetbrains.annotations.NotNull; @@ -25,7 +24,6 @@ import org.labkey.api.data.CompareType; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; -import org.labkey.api.data.ConvertHelper; import org.labkey.api.data.DbSchema; import org.labkey.api.data.DbScope; import org.labkey.api.data.Results; @@ -123,6 +121,8 @@ public class ONPRC_EHRTriggerHelper private static final String NONRESTRICTED = "Nonrestricted"; private static final String EXPERIMENTAL_EUTHANASIA = "EUTHANASIA, EXPERIMENTAL"; + private static final String NON_EXPERIMENTAL_EUTHANASIA = "EUTHANASIA, NONEXPERIMENTAL"; + private static final String SPONTANEOUS_DEATH = "Spontaneous Death"; public ONPRC_EHRTriggerHelper(int userId, String containerId) @@ -201,24 +201,24 @@ public Date onTreatmentOrderChange(Map row, Map Object current = row.get(field); if (current instanceof Number) { - current = ((Number)current).doubleValue(); + current = ((Number) current).doubleValue(); } else if (current instanceof String) { - current = StringUtils.trimToNull((String)current); + current = StringUtils.trimToNull((String) current); } Object old = oldRow.get(field); if (old instanceof Number) { - old = ((Number)old).doubleValue(); + old = ((Number) old).doubleValue(); } else if (old instanceof String) { - old = StringUtils.trimToNull((String)old); + old = StringUtils.trimToNull((String) old); } - if ((current == null && old != null ) || (current != null && old != null && !current.equals(old))) + if ((current == null && old != null) || (current != null && old != null && !current.equals(old))) { _log.info("change: " + field); hasChanged = true; @@ -232,8 +232,8 @@ else if (old instanceof String) // hasChanged = true; //} } - - if (hasChanged && hasTreatmentBeenGiven((Date)oldRow.get("date"), (Integer)oldRow.get("frequency")) && !hasTerminated((Date)oldRow.get("enddate"))) +// Modified: 7-13-2017 R.Blasa + if (hasChanged && hasTreatmentBeenGiven((Date) oldRow.get("date"), (Integer) oldRow.get("frequency")) && !hasTerminated((Date) oldRow.get("enddate"))) { return createUpdatedTreatmentRow(row, oldRow); } @@ -267,33 +267,19 @@ private List getEarliestFrequencyHours(int frequency) private boolean hasTreatmentBeenGiven(Date startDate, Integer frequency) { - if (frequency == null) - { - return false; - } - Date earliestDose = null; - List hours = getEarliestFrequencyHours(frequency); - if (hours != null) + Date earliestDose = null; + Boolean results =false; + Date curDate = new Date(); + earliestDose = startDate; + if (earliestDose.before(new Date())) { - for (Integer hour : hours) - { - Calendar timeToTest = Calendar.getInstance(); - timeToTest.setTime(startDate); - timeToTest.set(Calendar.HOUR_OF_DAY, (int) Math.floor(hour / 100)); - timeToTest.set(Calendar.MINUTE, hour % 100); - - if (timeToTest.getTime().getTime() >= startDate.getTime()) - { - earliestDose = timeToTest.getTime(); - break; - } - } + results = true; } - + return results; // return true if the earliest expected dose is before now - return earliestDose == null ? false : earliestDose.before(new Date()); +// return earliestDose == null ? false : earliestDose.before(new Date()); } public Date createUpdatedTreatmentRow(Map row, Map oldRow) throws Exception @@ -303,7 +289,7 @@ public Date createUpdatedTreatmentRow(Map row, Map> getAnimalLocationsAfterMove(String room, List row : housingRecords) { - String rowRoom = (String)row.get("room"); - String rowCage = (String)row.get("cage"); - String id = (String)row.get("Id"); + String rowRoom = (String) row.get("room"); + String rowCage = (String) row.get("cage"); + String id = (String) row.get("Id"); if (row.get("enddate") == null) { @@ -875,9 +861,9 @@ private Double getRequiredCageSize(Double weight, String requirementset) { if (requirementset == null || requirementset.equals(row.get("requirementset"))) { - if (weight >= (Double)row.get("low") && weight < (Double)row.get("high")) + if (weight >= (Double) row.get("low") && weight < (Double) row.get("high")) { - return (Double)row.get("sqft"); + return (Double) row.get("sqft"); } } } @@ -891,9 +877,9 @@ private Double getRequiredCageHeight(Double weight, String requirementset) { if (requirementset == null || requirementset.equals(row.get("requirementset"))) { - if (weight >= (Double)row.get("low") && weight < (Double)row.get("high")) + if (weight >= (Double) row.get("low") && weight < (Double) row.get("high")) { - return (Double)row.get("height"); + return (Double) row.get("height"); } } } @@ -907,7 +893,7 @@ public Integer getHousingType(String room) if (roomRec == null) return null; - return (Integer)roomRec.get("housingTypeInt"); + return (Integer) roomRec.get("housingTypeInt"); } public Integer getHousingCondition(String room) @@ -916,7 +902,7 @@ public Integer getHousingCondition(String room) if (roomRec == null) return null; - return (Integer)roomRec.get("housingConditionInt"); + return (Integer) roomRec.get("housingConditionInt"); } private List> getCageSizeRecords() @@ -1016,7 +1002,8 @@ else if (ret.size() > 1) } // Taken from DateUtils. should remove if we upgrade core - private Date maxDate(Date d1, Date d2) { + private Date maxDate(Date d1, Date d2) + { if (d1 == null && d2 == null) return null; if (d1 == null) return d2; if (d2 == null) return d1; @@ -1046,12 +1033,12 @@ public void closeActiveAssignmentRecords(String id, Date deathDate, String cause row.put("enddate", deathDate); + //Modified: 6-8-2018 R.Blasa All experimetal and Euthenized cause of death are automitaclly assigned 206 at release + if (EXPERIMENTAL_EUTHANASIA.equals(causeOfDeath) || NON_EXPERIMENTAL_EUTHANASIA.equals(causeOfDeath) || SPONTANEOUS_DEATH.equals(causeOfDeath) ) - //Modified: 6-28-2016 R.Blasa All experimetal and Euthenized cause of death are automitaclly assigned 206 at release - if (EXPERIMENTAL_EUTHANASIA.equals(causeOfDeath) ) { - row.put("releaseCondition", 206); + row.put("releaseCondition", 206); } @@ -1097,12 +1084,103 @@ public Map onAnimalArrival_AddDemographics(String id, Map row) throws QueryUpdateServiceException, DuplicateKeyException, SQLException, BatchValidationException + { + if (row.get("birth") != null) + { + Map birthProps = new HashMap<>(); + for (String key : new String[]{"Id", "dam", "sire"}) + { + if (row.containsKey(key)) + { + birthProps.put(key, row.get(key)); + } + } + birthProps.put("date", row.get("birth")); + birthProps.put("gender", row.get("gender")); + birthProps.put("species", row.get("species")); + birthProps.put("geographic_origin", row.get("geographic_origin")); + + //Added: 10-14-2016 R.Blasa + birthProps.put("Arrival_Date", row.get("date")); + + createBirthRecord_ONPRC(id, birthProps); + } + } + + //Added on 09/30/2016, L.Kolli + public void createBirthRecord_ONPRC(String id, Map props) throws QueryUpdateServiceException, DuplicateKeyException, SQLException, BatchValidationException + { + if (id == null) ///If AId is null, return + return; + + //Check if the AId exists in the Birth table + TableInfo ti1 = getTableInfo("study", "birth"); + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Id"), id, CompareType.EQUAL); + + TableSelector ts = new TableSelector(ti1, filter, null); + if (ts.exists()) + { + //Birth record found. Don't make duplicate entry + return; + } + else //Enter newly entered AnimalID into Birth table + { + TableInfo ti = getTableInfo("study", "birth"); + Map row = new CaseInsensitiveHashMap<>(); + row.putAll(props); + if (!row.containsKey("objectid")) + { + row.put("objectid", new GUID().toString()); + } + + List> rows = new ArrayList<>(); + rows.add(row); + BatchValidationException errors = new BatchValidationException(); + ti.getUpdateService().insertRows(getUser(), getContainer(), rows, errors, null, getExtraContext()); + + if (errors.hasErrors()) + throw errors; + } + + } + // Added: 6-27-2017 F.Blasa Process when transitioning from Prenatal - Fetus to Live + public void doBirthConditionAfterPrenatal(String id, Date date, String dam, Date Arrival_Date, String birthCondition, boolean isBecomingPublic) throws Exception + { + //is the infant is dead, terminate the assignments + Date enddate = isBirthAlive(birthCondition) ? null : date; + + String nonRestrictedFlag = getFlag("Condition", NONRESTRICTED, null, true); + if (nonRestrictedFlag != null) + { + //Modified: 10-14-2016 R.Blasa + Date Arrival_date = null; + if (Arrival_Date != null) + { + Arrival_date = Arrival_Date; + + } + else + { + Arrival_date = date; + } + //only add initial status if born alive + EHRService.get().ensureFlagActive(getUser(), getContainer(), nonRestrictedFlag, Arrival_date, enddate, null, Collections.singletonList(id), false); + } + else + { + _log.warn("Unable to find active flag for condition nonrestricted"); + } + } + + //Modified: 10-13-2016 R.Blasa to include assign Arrival date + public void doBirthTriggers(String id, Date date, String dam, Date Arrival_Date, String birthCondition, String species, boolean isBecomingPublic) throws Exception { //is the infant is dead, terminate the assignments Date enddate = isBirthAlive(birthCondition) ? null : date; + //also check for a pre-existing death record: Date deathDate = new TableSelector(getTableInfo("study", "deaths"), Collections.singleton("date"), new SimpleFilter(FieldKey.fromString("Id"), id), null).getObject(Date.class); if (deathDate != null) @@ -1116,18 +1194,60 @@ public void doBirthTriggers(String id, Date date, String dam, Date flagStartDate String nonRestrictedFlag = getFlag("Condition", NONRESTRICTED, null, true); if (nonRestrictedFlag != null) { - if (flagStartDate == null) + //Modified: 10-14-2016 R.Blasa + Date Arrival_date = null; + if (Arrival_Date != null) + { + Arrival_date = Arrival_Date; + + } + else { - flagStartDate = date; + Arrival_date = date; } + //only add initial status if born alive - EHRService.get().ensureFlagActive(getUser(), getContainer(), nonRestrictedFlag, flagStartDate, enddate, null, Collections.singletonList(id), false); + EHRService.get().ensureFlagActive(getUser(), getContainer(), nonRestrictedFlag, Arrival_date, enddate, null, Collections.singletonList(id), false); } else { _log.warn("Unable to find active flag for condition nonrestricted"); } + + + } +// Added: 10-27-2017 R.Blasa Create an SPR4 entries for Rhesus macaques + + if ("Live Birth".equalsIgnoreCase(birthCondition) && "RHESUS MACAQUE".equalsIgnoreCase(species) ) + + { + + String SPFFlag = getFlag("SPF", "SPF 4", null, true); + + TableInfo flagsSP4 = getTableInfo("study", "flags"); + SimpleFilter flagFilter = new SimpleFilter(FieldKey.fromString("Id"), id); + + //Note: Validate if SPF 4 is active + flagFilter.addCondition(FieldKey.fromString("flag/value"), "SPF 4"); + flagFilter.addClause(new SimpleFilter.OrClause( + new CompareType.CompareClause(FieldKey.fromString("enddate"), CompareType.DATE_GTE, date), + new CompareType.CompareClause(FieldKey.fromString("enddate"), CompareType.ISBLANK, null) + )); + + + TableSelector existingSP4 = new TableSelector(flagsSP4, Collections.singleton("flag"), flagFilter, null); + if (existingSP4.exists()) + { + _log.info("SP4 Flag active record exist for this monkey id: " + id + "Value") ; + } + else + { + _log.info("adding SP4 Animal : " + id + "Value"); + + EHRService.get().ensureFlagActive(getUser(), getContainer(), SPFFlag, date, enddate, null, Collections.singletonList(id), false); + + } } //NOTE: we allow this to run the first time this record is public with a non-null dam. this allows the record to be created without dam, then updated @@ -1210,7 +1330,8 @@ else if (flagList.size() > 1) new CompareType.CompareClause(FieldKey.fromString("enddate"), CompareType.DATE_GTE, date), new CompareType.CompareClause(FieldKey.fromString("enddate"), CompareType.ISBLANK, null) )); - assignmentFilter.addCondition(FieldKey.fromString("project/displayName"), PageFlowUtil.set(ONPRC_EHRManager.U42_PROJECT, ONPRC_EHRManager.U24_PROJECT), CompareType.IN); +// Modified:5-12-2017 Added Japanese Macaque Assignments + assignmentFilter.addCondition(FieldKey.fromString("project/displayName"), PageFlowUtil.set(ONPRC_EHRManager.U42_PROJECT, ONPRC_EHRManager.U24_PROJECT, ONPRC_EHRManager.JMAC_PROJECT), CompareType.IN); TableSelector ts3 = new TableSelector(assignment, Collections.singleton("project"), assignmentFilter, null); List assignmentList = ts3.getArrayList(Integer.class); @@ -1301,7 +1422,7 @@ public String checkForConditionDowngrade(String id, Date date, final Integer con List foundCodes = findHigherActiveConditonCodes(id, date, condition); if (!foundCodes.isEmpty()) { - return "Animal already has a higher condition code (" + (StringUtils.join(foundCodes, ","))+ "), cannot choose a lower code unless the existing code is removed or disabled"; + return "Animal already has a higher condition code (" + (StringUtils.join(foundCodes, ",")) + "), cannot choose a lower code unless the existing code is removed or disabled"; } return null; @@ -1389,8 +1510,8 @@ public void exec(ResultSet rs) throws SQLException { for (Map r : recordsInTransaction) { - String id = (String)r.get("Id"); - Number project = (Number)r.get("project"); + String id = (String) r.get("Id"); + Number project = (Number) r.get("project"); if (id == null || project == null) { continue; @@ -1600,7 +1721,7 @@ public String updateDividers(String id, String room, String cage, Integer divide } //first gather all animals currently housed, by cage - //Map> animalMap = getAnimalLocationsAfterMove(room, rowsInTransaction); + Map> animalMap = getAnimalLocationsAfterMove(room, rowsInTransaction); Set errors = new HashSet<>(); //also build list of existing dividers and changes @@ -1747,35 +1868,25 @@ else if (DbScope.getLabKeyScope().getSqlDialect().isSqlServer()) return _nextProtocolId; } - public boolean requiresAssistingStaff(Object procedureText) + public boolean requiresAssistingStaff(Integer procedureId) { - if (procedureText == null) + if (procedureId == null) { return false; } - try + if (!_cachedProcedureCategories.containsKey(procedureId)) { - Integer procedureId = ConvertHelper.convert(procedureText, Integer.class); - if (!_cachedProcedureCategories.containsKey(procedureId)) - { - TableInfo ti = getTableInfo("ehr_lookups", "procedures"); - TableSelector ts = new TableSelector(ti, PageFlowUtil.set("category"), new SimpleFilter(FieldKey.fromString("rowid"), procedureId), null); - String category = ts.getObject(String.class); - - _cachedProcedureCategories.put(procedureId, category); - } - - String category = _cachedProcedureCategories.get(procedureId); + TableInfo ti = getTableInfo("ehr_lookups", "procedures"); + TableSelector ts = new TableSelector(ti, PageFlowUtil.set("category"), new SimpleFilter(FieldKey.fromString("rowid"), procedureId), null); + String category = ts.getObject(String.class); - return "Surgery".equals(category); - } - catch (ConversionException e) - { - _log.warn("unable to convert procedureId to integer: [" + procedureText + "]", new Exception()); + _cachedProcedureCategories.put(procedureId, category); } - return false; + String category = _cachedProcedureCategories.get(procedureId); + + return "Surgery".equals(category); } public String getSpeciesForDam(String dam) @@ -1821,22 +1932,24 @@ public String validateObservation(String category, String observation) private Map> _cachedObservations = new HashMap<>(); - private @NotNull Set getAllowableObservations(String category) + private + @NotNull + Set getAllowableObservations(String category) { if (!_cachedObservations.containsKey(category)) { TableInfo ti = getTableInfo("ehr", "observation_types"); TableSelector ts = new TableSelector(ti, PageFlowUtil.set("schemaName", "queryName", "valuecolumn"), new SimpleFilter(FieldKey.fromString("value"), category), null); - Map record = ts.getMap(); + Map record = ts.getObject(Map.class); Set allowable; if (record != null && record.get("schemaname") != null && record.get("queryname") != null && record.get("valuecolumn") != null) { - TableInfo valuesTable = getTableInfo((String)record.get("schemaname"), (String)record.get("queryname")); + TableInfo valuesTable = getTableInfo((String) record.get("schemaname"), (String) record.get("queryname")); if (valuesTable != null) { allowable = new CaseInsensitiveHashSet(); - TableSelector ts2 = new TableSelector(valuesTable, PageFlowUtil.set((String)record.get("valuecolumn")), null, null); + TableSelector ts2 = new TableSelector(valuesTable, PageFlowUtil.set((String) record.get("valuecolumn")), null, null); allowable.addAll(ts2.getArrayList(String.class)); } else @@ -1964,7 +2077,6 @@ public void sendMenseNotifications(String id) } - //Added 9-2-2015 Blasa public void sendCullListNotifications(String id, String date, String flag) { @@ -2071,31 +2183,30 @@ public void sendProtocolNotifications(String protocolid) html.append("Iacuc Protocol Investigator Iacuc Approval Date\n"); ts.forEach(new Selector.ForEachBlock() - { - - @Override - public void exec(ResultSet rs) throws SQLException - { - - //Translate Investigator id to its true name - TableInfo ti2 = getTableInfo("onprc_ehr", "investigators"); - SimpleFilter filter2 = new SimpleFilter(FieldKey.fromString("rowid"), rs.getString("investigatorId")); - filter2.addCondition(FieldKey.fromString("datedisabled"), true, CompareType.ISBLANK); - - TableSelector ts2 = new TableSelector(ti2, PageFlowUtil.set("lastname"), filter2, null); - List ret2 = ts2.getArrayList(String.class); - if (ret2 != null && !ret2.isEmpty()) { - for (String Investname : ret2) + + @Override + public void exec(ResultSet rs) throws SQLException { - //html.append("" + (rs.getString("external_id") == null ? "" : rs.getString("external_id")) + "" + Investname + "" + rs.getString("approve") + "\n"); - html.append("" + (rs.getString("external_id") == null ? "" : rs.getString("external_id")) + " " + Investname + " " + rs.getString("approve") + "\n"); - break; + + //Translate Investigator id to its true name + TableInfo ti2 = getTableInfo("onprc_ehr", "investigators"); + SimpleFilter filter2 = new SimpleFilter(FieldKey.fromString("rowid"), rs.getString("investigatorId")); + filter2.addCondition(FieldKey.fromString("datedisabled"), true, CompareType.ISBLANK); + + TableSelector ts2 = new TableSelector(ti2, PageFlowUtil.set("lastname"), filter2, null); + List ret2 = ts2.getArrayList(String.class); + if (ret2 != null && !ret2.isEmpty()) + { + for (String Investname : ret2) + { + html.append("" + (rs.getString("external_id") == null ? "" : rs.getString("external_id")) + " " + Investname + " " + rs.getString("approve") + "\n"); + break; + } + } } - } - } - } + } ); @@ -2108,7 +2219,7 @@ public void exec(ResultSet rs) throws SQLException } - //Added 9-2-2015 Blasa + //Added 9-2-2015 Blasa private void sendMessage(String subject, String bodyHtml, Collection recipients) { try @@ -2148,4 +2259,68 @@ private void sendMessage(String subject, String bodyHtml, Collection ids) throws Exception + { + TableInfo ti = getTableInfo("study", "demographicsGeneticAncestry"); + if (ti == null) + { + return; + } + + Set keys = new HashSet<>(); + keys.add(FieldKey.fromString("Id")); + keys.add(FieldKey.fromString("Id/demographics/lsid")); + keys.add(FieldKey.fromString("Id/demographics/geographic_origin")); + keys.add(FieldKey.fromString("geneticAncestry")); + final Map colMap = QueryService.get().getColumns(ti, keys); + + final List> toUpdate = new ArrayList<>(); + final List> oldKeys = new ArrayList<>(); + TableSelector ts = new TableSelector(ti, colMap.values(), new SimpleFilter(FieldKey.fromString("Id"), ids, CompareType.IN), null); + ts.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet object) throws SQLException + { + ResultsImpl rs = new ResultsImpl(object, colMap); + String origin = rs.getString(FieldKey.fromString("Id/demographics/geographic_origin")); + String geneticAncestry = rs.getString(FieldKey.fromString("geneticAncestry")); + String lsid = rs.getString(FieldKey.fromString("Id/demographics/lsid")); + if (lsid != null && geneticAncestry != null && !geneticAncestry.equals(origin)) + { + Map row = new CaseInsensitiveHashMap<>(); + row.put("lsid", lsid); + row.put("geographic_origin", geneticAncestry); + Map keyRow = new CaseInsensitiveHashMap<>(); + keyRow.put("lsid", lsid); + + oldKeys.add(keyRow); + toUpdate.add(row); + } + + } + }); + + if (!toUpdate.isEmpty()) + { + TableInfo demographics = getTableInfo("study", "demographics"); + demographics.getUpdateService().updateRows(_user, _container, toUpdate, oldKeys, null, getExtraContext()); + } + } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java index 0ecc0d611..bf1f09113 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java @@ -852,6 +852,7 @@ private void customizeCasesTable(AbstractTableInfo ti) { appendLatestHxCol(ti); appendSurgeryCol(ti); + appendSurgeryFollupDaysyCol(ti); //Added: 11/1/2017 R.Blasa appendCaseHistoryCol(ti); String problemCategories = "problemCategories"; @@ -1061,6 +1062,12 @@ private void customizeTreatmentOrdersTable(AbstractTableInfo ti) { ti.getMutableColumn("qualifier").setHidden(true); } + + if (ti.getColumn("isActive") != null) + { + ti.removeColumn(ti.getColumn("isActive")); + EHRService.get().addIsActiveCol(ti, true, EHRService.EndingOption.endsToday, EHRService.EndingOption.activeAfterMidnightTonight); + } } private void customizeTreatmentFrequency(AbstractTableInfo ti) @@ -1335,6 +1342,17 @@ private void appendLatestHxCol(AbstractTableInfo ti) recentRemark.setDisplayWidth("200"); ti.addColumn(recentRemark); + //don't use caseId. CEg Plan info Added: 10-25-2017 R.Blasa + SQLFragment recentCeg_Plansql = new SQLFragment("(SELECT " + prefix + " (" + "r.CEG_Plan" + ") as _expr FROM " + realTable.getSelectName() + + " r WHERE " +// + " r.caseid = " + ExprColumn.STR_TABLE_ALIAS + ".objectid AND " + + " r.participantId = " + ExprColumn.STR_TABLE_ALIAS + ".participantId AND r.CEG_Plan IS NOT NULL AND (r.category != ? OR r.category IS NULL) ORDER BY r.date desc " + suffix + ")", ONPRC_EHRManager.REPLACED_SOAP); + ExprColumn recentCeg_plan = new ExprColumn(ti, "mostRecentCeg_Plan", recentCeg_Plansql, JdbcType.VARCHAR, objectId); + recentCeg_plan.setLabel("Most Recent Ceg Plan For Case"); + recentCeg_plan.setDescription("This column will display the most recent CEG Plan that has been entered for the animal."); + recentCeg_plan.setDisplayWidth("200"); + ti.addColumn(recentCeg_plan); + //does not use caseId SQLFragment p2Sql = new SQLFragment("(SELECT " + ti.getSqlDialect().getGroupConcat(new SQLFragment(ti.getSqlDialect().concatenate("'P2: '", "r.p2")), true, false, chr + "(10)").getSqlCharSequence() + " FROM " + realTable.getSelectName() + " r WHERE " @@ -1420,6 +1438,35 @@ private void appendSurgeryCol(AbstractTableInfo ti) ti.addColumn(procedureCol); } + //Added: 11-1-2017 R.Blasa + private void appendSurgeryFollupDaysyCol(AbstractTableInfo ti) + { + String name = "surgeryfollowupDays"; + if (ti.getColumn(name) != null) + return; + + TableInfo realTable = getRealTableForDataset(ti, "Clinical Encounters"); + if (realTable == null) + { + _log.warn("Unable to find real table for clin encounters"); + return; + } + + //find any surgical procedures from the same date as this case + String chr = ti.getSqlDialect().isPostgreSQL() ? "chr" : "char"; + SQLFragment procedureSql = new SQLFragment("(SELECT cast(max(p.followupDays) as varchar(2))" + + " FROM " + realTable.getSelectName() + " r " + + " JOIN ehr_lookups.procedures p ON (p.rowid = r.procedureid) " + + //r.caseid = " + ExprColumn.STR_TABLE_ALIAS + ".objectid AND + " WHERE r.participantId = " + ExprColumn.STR_TABLE_ALIAS + ".participantId " + + " AND CAST(r.date AS date) = CAST(" + ExprColumn.STR_TABLE_ALIAS + ".date as date) " + + " AND r.type = 'Surgery' )"); + ExprColumn procedureCol = new ExprColumn(ti, name, procedureSql, JdbcType.VARCHAR, ti.getColumn("date")); + procedureCol.setLabel("Procedures Surgery Follow up Days"); + procedureCol.setDisplayWidth("100"); + ti.addColumn(procedureCol); + } + private void customizeTasks(AbstractTableInfo ti) { DetailsURL detailsURL = DetailsURL.fromString("/ehr/dataEntryFormDetails.view?formType=${formtype}&taskid=${taskid}"); diff --git a/onprc_reports/resources/queries/study/processingBloodDraws.query.xml b/onprc_reports/resources/queries/study/processingBloodDraws.query.xml index fa9bd4fed..e0e1213be 100644 --- a/onprc_reports/resources/queries/study/processingBloodDraws.query.xml +++ b/onprc_reports/resources/queries/study/processingBloodDraws.query.xml @@ -7,6 +7,9 @@ Is U42? + + PCR Blood Volume (mL) + Serology Blood Vol (mL) diff --git a/onprc_reports/resources/queries/study/processingBloodDraws.sql b/onprc_reports/resources/queries/study/processingBloodDraws.sql index 3034a9392..d020c227b 100644 --- a/onprc_reports/resources/queries/study/processingBloodDraws.sql +++ b/onprc_reports/resources/queries/study/processingBloodDraws.sql @@ -2,12 +2,19 @@ SELECT d.Id, g.isU42, s.spfStatus, + Case when g.isU42 = 'Y' And (s.bloodVol > 0 ) then 2 + ELSE + 0 + End as PCRBloodVolume, s.bloodVol as serologyBloodVol, g.parentageBloodDrawVol, g.mhcBloodDrawVol, g.dnaBloodDrawVol, g.totalBloodDrawVol as geneticsBloodVol, - coalesce(s.bloodVol, 0) + coalesce(g.totalBloodDrawVol, 0) as totalBloodDrawVol + coalesce(s.bloodVol, 0) + Case when g.isU42 = 'Y'And (s.bloodVol > 0 ) then 2 + ELSE + 0 + End + coalesce(g.totalBloodDrawVol, 0) as totalBloodDrawVol FROM study.demographics d diff --git a/onprc_reports/resources/queries/study/processingBloodDraws/.qview.xml b/onprc_reports/resources/queries/study/processingBloodDraws/.qview.xml index fb7cc3262..c1bac19ad 100644 --- a/onprc_reports/resources/queries/study/processingBloodDraws/.qview.xml +++ b/onprc_reports/resources/queries/study/processingBloodDraws/.qview.xml @@ -1,15 +1,16 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_reports/resources/queries/study/processingGeneticsBloodDraws.sql b/onprc_reports/resources/queries/study/processingGeneticsBloodDraws.sql index 52b872ba9..5c72fce67 100644 --- a/onprc_reports/resources/queries/study/processingGeneticsBloodDraws.sql +++ b/onprc_reports/resources/queries/study/processingGeneticsBloodDraws.sql @@ -6,6 +6,7 @@ SELECT t.geographic_origin, t.gender, t.isU42, + t.isESPF, t.flags, t.parentageBloodDrawVol, t.mhcBloodDrawVol, @@ -24,6 +25,10 @@ SELECT WHEN (a.Id IS NULL) THEN 'N' ELSE 'Y' END as isU42, + CASE + WHEN (u.Id IS NULL) THEN 'N' + ELSE 'Y' + END as isESPF, f.flags, CASE WHEN (f.flags LIKE '%Parentage Blood Draw Needed%') THEN 1 @@ -36,11 +41,13 @@ SELECT END as parentageBloodDrawVol, --Note: MHC draws are being taken on all U42 Animals (Males and females) and non-U42 males only --Note: if changing this logic, mhcFlagSummary.sql should also be updated + --Note: Issue Tracker 4128 changed the method relating to ESPF Animals as depicted in line 48 and 49 CASE WHEN (f.flags LIKE '%MHC Blood Draw Needed%') THEN 1 WHEN (f.flags LIKE '%MHC Typing Not Needed%') THEN 0 WHEN (f.flags LIKE '%MHC Blood Draw Collected%') THEN 0 - WHEN (d.species = 'RHESUS MACAQUE' AND d.Id.age.ageInYears <= 5.0 AND d.geographic_origin = 'India' AND m.Id IS NULL AND (a.Id IS NOT NULL OR d.gender = 'm')) THEN 1 + WHEN (d.species = 'RHESUS MACAQUE' AND d.Id.age.ageInYears <= 5.0 AND d.geographic_origin = 'India' AND m.Id IS NULL AND (a.Id IS NOT NULL OR d.gender = 'm' ) and u.id is null ) THEN 1 + WHEN (u.id is not Null and d.Id.age.ageInYears <= 10.0 and d.Id.age.ageInMonths >= 6 ) then 1 ELSE 0 END as mhcBloodDrawVol, CASE @@ -133,6 +140,17 @@ LEFT JOIN ( GROUP BY a.Id ) a ON (a.Id = d.Id) +--U24 ESPF +LEFT JOIN ( + SELECT + u.Id + --count(*) as total + FROM study.assignment u + WHERE u.isActive = true and u.project.name = javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.U24_PROJECT') + GROUP BY u.Id +) u ON (u.Id = d.Id) + + WHERE d.calculated_status = 'Alive' ) t \ No newline at end of file diff --git a/onprc_reports/resources/queries/study/samples.sql b/onprc_reports/resources/queries/study/samples.sql index a6d976be9..66573f909 100644 --- a/onprc_reports/resources/queries/study/samples.sql +++ b/onprc_reports/resources/queries/study/samples.sql @@ -9,6 +9,7 @@ concentration, concentration_units, quantity, quantity_units, -comment +comment, +dateremoved --retain this column since downstream queries still filter on it. more complete fix added to trunk FROM laboratory.samples WHERE dateremoved IS NULL \ No newline at end of file diff --git a/onprc_ssu/resources/queries/onprc_ssu/schedule.js b/onprc_ssu/resources/queries/onprc_ssu/schedule.js index d08f3c964..4a69359e4 100644 --- a/onprc_ssu/resources/queries/onprc_ssu/schedule.js +++ b/onprc_ssu/resources/queries/onprc_ssu/schedule.js @@ -9,8 +9,6 @@ var LABKEY = require("labkey"); var helper = org.labkey.ldk.query.LookupValidationHelper.create(LABKEY.Security.currentContainer.id, LABKEY.Security.currentUser.id, 'onprc_ssu', 'schedule'); -console.log("** evaluating: " + this['javax.script.filename']); - function beforeInsert(row, errors){ beforeUpsert(row, errors); diff --git a/sla/resources/queries/sla/ProtocolProjectsUsage.sql b/sla/resources/queries/sla/ProtocolProjectsUsage.sql index d554dafc6..5de540786 100644 --- a/sla/resources/queries/sla/ProtocolProjectsUsage.sql +++ b/sla/resources/queries/sla/ProtocolProjectsUsage.sql @@ -24,11 +24,22 @@ LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.sla.al LEFT JOIN (select * from onprc_billing.projectAccountHistory z where (z.StartDate IS NOT NULL AND z.EndDate IS NOT NULL AND now() between z.StartDate AND z.EndDate)) x ON a.project = x.project LEFT JOIN "/onprc/admin/finance/public".onprc_billing_public.aliases y ON y.alias = x.account LEFT JOIN ( - SELECT i.protocol,species,gender,sum(animalsreceived) AS NumUsed - FROM sla.purchasedetails pd, sla.purchase p - LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i ON p.project = i.project - WHERE p.objectid = pd.purchaseid AND animalsreceived IS NOT NULL - GROUP BY i.protocol,species,gender +-- SELECT i.protocol,species,gender,sum(animalsreceived) AS NumUsed +-- FROM sla.purchasedetails pd, sla.purchase p +-- LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i ON p.project = i.project +-- WHERE p.objectid = pd.purchaseid AND animalsreceived IS NOT NULL +-- GROUP BY i.protocol,species,gender +--Changed by LK on 5/30 to get the accurate numused. + (SELECT i.protocol,pd.species,pd.gender,sum(animalsreceived) AS NumUsed + FROM sla.purchasedetails pd, sla.purchase p, Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i, + Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.sla.allowableAnimals aa1 + Where p.project = i.project AND p.objectid = pd.purchaseid + AND aa1.protocol = i.protocol AND aa1.species = pd.species AND aa1.gender = pd.gender + AND animalsreceived IS NOT NULL + AND (p.orderdate between aa1.StartDate AND aa1.EndDate) AND aa1.enddate > now() + --And i.project = 2167 + GROUP BY i.protocol, pd.species, pd.gender) + ) AS calc ON a.protocol = calc.protocol AND (aa.species = calc.species OR (aa.species IS NULL AND calc.species IS NULL)) AND (aa.gender = calc.gender OR (aa.gender IS NULL AND calc.gender IS NULL)) @@ -39,7 +50,7 @@ WHERE (aa.StartDate IS NOT NULL AND aa.EndDate IS NULL AND now() > aa.StartDate) OR (aa.StartDate IS NULL AND aa.EndDate IS NOT NULL AND now() < aa.EndDate) OR (now() between aa.StartDate AND aa.EndDate) - --(x.StartDate IS NOT NULL AND x.EndDate IS NOT NULL AND now() between x.StartDate AND x.EndDate) + --(aa.StartDate IS NOT NULL AND aa.EndDate IS NOT NULL AND now() between aa.StartDate AND aa.EndDate) ) -- and filtered based on dataAccess for the given user AND diff --git a/sla/resources/queries/sla/SLACageSize.sql b/sla/resources/queries/sla/SLACageSize.sql index 3abf57b9f..d811d9159 100644 --- a/sla/resources/queries/sla/SLACageSize.sql +++ b/sla/resources/queries/sla/SLACageSize.sql @@ -6,10 +6,9 @@ /* Created Blasa 2-13-2015 Provide Distinct SLA Cage Size Reference table */ - select distinct cagesize - from onprc_billing.slaPerDiemFeeDefinition b - Where active = True - order by cagesize - + select value + from sla.Reference_Data + Where columnName = 'cagesize' + order by sort_order diff --git a/sla/resources/queries/sla/SLACageType.sql b/sla/resources/queries/sla/SLACageType.sql index 9c34883e0..d1a216b51 100644 --- a/sla/resources/queries/sla/SLACageType.sql +++ b/sla/resources/queries/sla/SLACageType.sql @@ -5,11 +5,12 @@ */ /* Created Blasa 2-13-2015 Provide Distinct SLA Cage Type Reference table */ +-- Modified:R.blasa 5-23-2017 - select distinct cagetype - from onprc_billing.slaPerDiemFeeDefinition b - Where active = True - order by cagetype + select value + from sla.Reference_Data + Where columnName = 'cagetype' + order by sort_order diff --git a/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql b/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql index 111d37264..d9c3c2f35 100644 --- a/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql +++ b/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql @@ -3,6 +3,7 @@ SELECT '[Update order]' AS updatelink, '[Print view]' AS printviewlink, p.rowid, +p.requestdate, p.projectname, p.protocol, p.investigator, @@ -16,14 +17,13 @@ pd.weight, pd.gestation, pd.room, pd.animalsordered, -p.requestdate, pd.expectedarrivaldate, -pd.housingInstructions, p.confirmationnum, p.housingconfirmed, p.orderdate, pd.sla_DOB, pd.vendorLocation, +pd.housingInstructions, pd.receiveddate, pd.receivedby, pd.datecancelled, diff --git a/sla/resources/schemas/sla.xml b/sla/resources/schemas/sla.xml index f3160402a..36018f4f1 100644 --- a/sla/resources/schemas/sla.xml +++ b/sla/resources/schemas/sla.xml @@ -63,7 +63,7 @@ /ONPRC/EHR sla SLACageType - cagetype + value
@@ -73,7 +73,7 @@ /ONPRC/EHR sla SLACageSize - cagesize + value
diff --git a/sla/resources/web/sla/form/CreatePurchaseOrder.js b/sla/resources/web/sla/form/CreatePurchaseOrder.js index 6e0664a21..dad8ec453 100644 --- a/sla/resources/web/sla/form/CreatePurchaseOrder.js +++ b/sla/resources/web/sla/form/CreatePurchaseOrder.js @@ -3,6 +3,7 @@ * a purchase order (see createPurchaseOrder.html and updatePurchaseOrder.html for usages). */ Ext4.define('SLA.panel.PurchaseOrderRequest', { + extend: 'Ext.panel.Panel', bodyStyle: 'background-color: transparent;', @@ -20,7 +21,27 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { */ initComponent: function() { - // add the initial form sections, start with just the protocol form if this is not an update + //Ext4.apply(this, { + // bodyStyle: 'padding: 5px;', + // defaults: { + // border: false + // }, + // items: [{ + // html: 'The birth/arrival screen will be disabled as a default. You must enable the form in order to:
  • Get an Animal ID(s)
  • Secure the numbers for processing
  • Finish entering data on acquired numbers

When you enable the form for data entry all others will automatically be blocked from using the form.
Once you "Submit for Review" or "Save and Close", the birth/arrival form will be automatically be available for all other users. If you do not submit/save please click the button below to exit data entry before leaving, otherwise all other users will be permanently locked out.

If the birth/arrival form is unavailable and you believe it has been kept locked by mistake please first contact the person who locked the form. If they cannot be reached and it is a weekday please e-mail onprcitsupport@ohsu.edu with the subject "Priority 1 Work Stoppage: birth/arrival Form Locked". If it is a weekend please contact an RFO lead tech. Please take care not to request the birth/arrival form be unlocked unless you are confident the lock is in error, otherwise you will kick a user out of the birth/arrival form and prevent data entry.' , + // style: 'padding-bottom: 10px;' + // },{ + // itemId: 'infoArea', + // border: false + // },{ + // layout: 'hbox', + // defaults: { + // style: 'margin-right: 5px;' + // }, + // }] + //}); + + + // add the initial form sections, start with just the protocol form if this is not an update var items = [ this.getProtocolForm(), this.getPurchaseForm(), @@ -42,6 +63,8 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { this.callParent(); }, + + /** * Initialize the Ext panel for selecting the IACUC protocol for a purchase order. * @returns {SLA.form.ProtocolForm} @@ -434,13 +457,14 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { } //added by Kolli - if (speciesRowData.location == 'NSI 0123D' || speciesRowData.location == 'NSI 0125D' ) + if (speciesRowData.room == 'NSI 0123D' || speciesRowData.room == 'NSI 0125D' ) { isHazardsRequired = true; } }, this); - if (isHazardsRequired && (purchaseData.listHazard == null || purchaseData.listHazard == '')) + //if (isHazardsRequired && (purchaseData.listHazard == null || purchaseData.listHazard == '')) + if (isHazardsRequired && (purchaseData.hazardslist == null || purchaseData.hazardslist == '')) { this.showErrorMsg('You have selected Location(s): NSI 0123D or NSI 0125D. Please list the biological or chemical agents! '); return; @@ -855,15 +879,232 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { success: function (response) { this.showSuccess(rowId); + this.insertMiscCharges(rowId,newPurchaseData); } }); } else { this.showSuccess(rowId); + this.insertMiscCharges(rowId,newPurchaseData); } + }, + ////Kollil: If the new receiving info is entered, Insert a row into the onprc_billing.miscCharges table + //insertMiscCharges : function (rowId,newPurchaseData) + //{ + // var miscCharges=[]; + // var prevDetailsMap = {}; + // var vendor_id ; + // + // //Get the vendor id for the given name + // LABKEY.Query.executeSql({ + // method: 'POST', + // schemaName: 'sla_public', + // sql: "Select objectid from vendors where name = 'ONPRC Weaning - SLA'", + // //failure: LDK.Utils.getErrorCallback(), + // success: function(data) + // { + // // we expect exactly one row in the response, so if that is not the case return an 'Invalid' error + // if (data.rows.length != 1) + // { + // response.error = 'Invalid vendorid'; + // callback.call(scope, response); + // } + // else + // { + // vendor_id = data.rows[0].objectid; + // + // // } + // // } + // //}); + // // Get previous purchase data + // Ext4.each(this.initData.species, function (speciesRow) + // { + // prevDetailsMap[speciesRow['objectid']] = speciesRow; + // }); + // // Get New purchase data + // Ext4.each(newPurchaseData.details, function (detailsRow) + // { + // var objectid = detailsRow['objectid'], + // receiveddate = Ext4.isDate(detailsRow['receiveddate']) ? Ext4.util.Format.date(detailsRow['receiveddate'], 'Y-m-d') : this.trimDateToYMDStr(detailsRow['receiveddate']), + // receivedby = detailsRow['receivedby']; + // + // if (Ext4.isDefined(prevDetailsMap[objectid])) + // { + // var prevReceiveddate = this.trimDateToYMDStr(prevDetailsMap[objectid]['receiveddate']), + // prevReceivedby = prevDetailsMap[objectid]['receivedby']; + // + // //Compare the receiving info with the previous data + // if ((prevReceiveddate == null & receiveddate != null) || (prevReceivedby == null & receivedby != null)) + // { + // //if (newPurchaseData['vendorid.name'] == 'ONPRC Weaning - SLA') + // if (newPurchaseData['vendorid'] == vendor_id) + // { + // miscCharges.push({ + // "date": receiveddate, + // "project": newPurchaseData['project'], + // "objectid": LABKEY.Utils.generateUUID(), + // //"category": 'SLA Fees', + // "chargeType": 'SLAU', + // "chargeId": 5398, //Chargeableitem: ChargeName = 'SLAU Weaning Fee', ChargeID = 5398 + // "quantity": 1, //detailsRow['NumAnimalsReceived'], + // "comment": 'SLA Weaning', + // }); + // } + // else + // { + // miscCharges.push({ + // "date": receiveddate, + // "project": newPurchaseData['project'], + // "objectid": LABKEY.Utils.generateUUID(), + // //"category": 'SLA Fees', + // "chargeType": 'SLAU', + // "chargeId": 5331, //Chargeableitem: ChargeName = 'SLAU Animal Purchase', ChargeID = 5331 + // "quantity": 1, //detailsRow['NumAnimalsReceived'], + // "comment": 'SLA Purchase billing', + // }); + // } + // } + // } + // },this); + // + // if (miscCharges.length > 0 ) + // { + // LABKEY.Query.insertRows({ + // containerPath: '/ONPRC/EHR', + // schemaName: 'onprc_billing', + // queryName: 'miscCharges', + // rows: miscCharges, + // scope: this, + // success: function () + // { + // this.showSuccess(rowId); + // }, + // failure: function(response) + // { + // console.error(response.exception); + // this.showErrorMsg(response.exception); + // } + // }); + // } + // else + // { + // this.showSuccess(rowId); + // } + // + // } + // } + // }); + //}, + + + //Kollil: If the new receiving info is entered, Insert a row into the onprc_billing.miscCharges table + insertMiscCharges : function (rowId,newPurchaseData) + { + var miscCharges=[]; + var prevDetailsMap = {}; + //var vendor_id ; + + ////Get the vendor id for the given name + //LABKEY.Query.executeSql({ + // method: 'POST', + // schemaName: 'sla_public', + // sql: "Select objectid from vendors where name = 'ONPRC Weaning - SLA'", + // //failure: LDK.Utils.getErrorCallback(), + // success: function(data) + // { + // // we expect exactly one row in the response, so if that is not the case return an 'Invalid' error + // if (data.rows.length != 1) + // { + // response.error = 'Invalid vendorid'; + // callback.call(scope, response); + // } + // else + // { + // vendor_id = data.rows[0].objectid; + // } + // } + //}); + + // Get previous purchase data + Ext4.each(this.initData.species, function (speciesRow) + { + prevDetailsMap[speciesRow['objectid']] = speciesRow; + }); + // Get New purchase data + Ext4.each(newPurchaseData.details, function (detailsRow) + { + var objectid = detailsRow['objectid'], + receiveddate = Ext4.isDate(detailsRow['receiveddate']) ? Ext4.util.Format.date(detailsRow['receiveddate'], 'Y-m-d') : this.trimDateToYMDStr(detailsRow['receiveddate']), + receivedby = detailsRow['receivedby']; + + if (Ext4.isDefined(prevDetailsMap[objectid])) + { + var prevReceiveddate = this.trimDateToYMDStr(prevDetailsMap[objectid]['receiveddate']), + prevReceivedby = prevDetailsMap[objectid]['receivedby']; + + //Compare the receiving info with the previous data + if ((prevReceiveddate == null & receiveddate != null) || (prevReceivedby == null & receivedby != null)) + { + if (this.initData.purchase.vendor == 'ONPRC Weaning - SLA') + //if (newPurchaseData['vendorid'] == vendor_id) + { + miscCharges.push({ + "date": receiveddate, + "project": newPurchaseData['project'], + "objectid": LABKEY.Utils.generateUUID(), + //"category": 'SLA Fees', + "chargeType": 'SLAU', + "chargeId": 5398, //Chargeableitem: ChargeName = 'SLAU Weaning Fee', ChargeID = 5398 + "quantity": 1, //detailsRow['NumAnimalsReceived'], + "comment": 'SLA Weaning', + }); + } + else + { + miscCharges.push({ + "date": receiveddate, + "project": newPurchaseData['project'], + "objectid": LABKEY.Utils.generateUUID(), + //"category": 'SLA Fees', + "chargeType": 'SLAU', + "chargeId": 5331, //Chargeableitem: ChargeName = 'SLAU Animal Purchase', ChargeID = 5331 + "quantity": 1, //detailsRow['NumAnimalsReceived'], + "comment": 'SLA Purchase billing', + }); + } + } + } + },this); + + if (miscCharges.length > 0 ) + { + LABKEY.Query.insertRows({ + containerPath: '/ONPRC/EHR', + schemaName: 'onprc_billing', + queryName: 'miscCharges', + rows: miscCharges, + scope: this, + success: function () + { + this.showSuccess(rowId); + }, + failure: function(response) + { + console.error(response.exception); + this.showErrorMsg(response.exception); + } + }); + } + else + { + this.showSuccess(rowId); + } + }, + + trimDateToYMDStr : function(val) { var newVal = val != null && val.indexOf(' ') > 0 ? val.substring(0, val.indexOf(' ')) : val; diff --git a/sla/resources/web/sla/form/PurchaseOrder.css b/sla/resources/web/sla/form/PurchaseOrder.css index b0d9ec600..574ab5f6b 100644 --- a/sla/resources/web/sla/form/PurchaseOrder.css +++ b/sla/resources/web/sla/form/PurchaseOrder.css @@ -14,6 +14,11 @@ border-radius: 5px; } +.order-dashboard-warning { + color: #ff0000; + font-weight: bold; +} + .order-dashboard-summary .order-dashboard-item a { font-weight: bold; } diff --git a/sla/resources/web/sla/form/PurchaseOrderDashboard.js b/sla/resources/web/sla/form/PurchaseOrderDashboard.js index 46193d212..354ee4fd7 100644 --- a/sla/resources/web/sla/form/PurchaseOrderDashboard.js +++ b/sla/resources/web/sla/form/PurchaseOrderDashboard.js @@ -159,7 +159,7 @@ Ext4.define('SLA.panel.PurchaseOrderDashboard', { data: data, tpl: new Ext4.XTemplate( '', - + '
Note: All purchase requests must be recieved no later than WEDNESDAY NOON for shipments next week. If you have any questions, Please contact, Kati Marshall: marshalk@ohsu.edu

', '
', '
Data Entry
', '', diff --git a/sla/resources/web/sla/form/PurchaseOrderDetails.js b/sla/resources/web/sla/form/PurchaseOrderDetails.js index 328296f7e..bd13ce256 100644 --- a/sla/resources/web/sla/form/PurchaseOrderDetails.js +++ b/sla/resources/web/sla/form/PurchaseOrderDetails.js @@ -123,12 +123,11 @@ Ext4.define('SLA.panel.PurchaseOrderDetails', { 'WEIGHT: {weight:htmlEncode}
', 'GESTATION: {gestation:htmlEncode}
', 'NUM ANIMALS ORDERED: {animalsordered}
', + 'SPECIAL INSTRUCTIONS: {housinginstructions:htmlEncode}
', 'REQUESTED ARRIVAL DATE: {requestedarrivaldate}
', 'EXPECTED ARRIVAL DATE: {expectedarrivaldate}
', 'SLA_DOB: {sla_DOB}
', 'SLA VENDOR LOCATION: {vendorLocation}
', - 'SPECIAL INSTRUCTIONS: {housinginstructions:htmlEncode}
', - '
', '
', '' diff --git a/sla/resources/web/sla/form/PurchaseSpeciesGrid.js b/sla/resources/web/sla/form/PurchaseSpeciesGrid.js index 5f2147a44..506d6580f 100644 --- a/sla/resources/web/sla/form/PurchaseSpeciesGrid.js +++ b/sla/resources/web/sla/form/PurchaseSpeciesGrid.js @@ -207,7 +207,7 @@ Ext4.define('SLA.form.SpeciesGrid', { editor: { // use the input field that validates input as text xtype: 'datefield', - minValue: new Date() + //minValue: new Date() } }, { diff --git a/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql b/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql index 5f5cbb563..19f76a089 100644 --- a/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql +++ b/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql @@ -106,7 +106,8 @@ WHERE t1.date is not null ) s ON (s.animalid = d.id) -WHERE d.calculated_status = 'Alive' +WHERE --d.calculated_status = 'Alive' --account for date/time in schedule -and s.date >= s.startDate and s.date <= s.enddate +--and +s.date >= s.startDate and s.date <= s.enddate From f21297f6321e91fcd6c231a899d8e777b2723d96 Mon Sep 17 00:00:00 2001 From: Binal Date: Tue, 6 Oct 2020 14:12:33 -0700 Subject: [PATCH 02/49] Merge from onprc19.1 r.63271 (includes newly created folders & files that didn't find the new base automatically) --- .../postgresql/geneticscore-17.10-17.11.sql | 45 +++ .../sqlserver/geneticscore-17.10-17.11.sql | 45 +++ ONPRC_EHR_ComplianceDB/module.properties | 4 + .../resources/views/begin.html | 72 +++++ .../resources/views/begin.view.xml | 5 + .../resources/views/begin.webpart.xml | 9 + .../views/printableComplianceReports.html | 266 ++++++++++++++++ .../views/printableComplianceReports.view.xml | 6 + .../queries/extscheduler/SchedulerAliases.sql | 10 + .../extscheduler/SchedulerAliases/.qview.xml | 11 + .../sqlserver/extscheduler-15.28-15.29.sql | 1 + .../sqlserver/extscheduler-15.29-15.30.sql | 1 + .../sqlserver/extscheduler-15.30-15.31.sql | 21 ++ .../resources/etls/rateChangeUpdate.xml | 27 ++ .../MiscChargesNotBilled_Virology.sql | 49 +++ .../miscChargesNotBilled_Virology.query.xml | 123 ++++++++ .../queries/onprc_billing/virologyAliases.sql | 7 + .../onprc_billing/virologyBillingCharges.sql | 4 + .../resources/queries/virologyAliases.sql | 3 + .../sqlserver/onprc_billing-12.380-12.381.sql | 13 + .../sqlserver/onprc_billing-17.410-17.411.sql | 23 ++ .../sqlserver/onprc_billing-17.411-17.412.sql | 4 + .../sqlserver/onprc_billing-17.412-17.413.sql | 4 + .../sqlserver/onprc_billing-17.501-17.502.sql | 285 ++++++++++++++++++ .../onprc_billing/model/sources/AliasMisc.js | 23 ++ .../model/sources/VirologyMisc.js | 108 +++++++ .../ChargesVirologyCoreFormSection.java | 60 ++++ .../ChargesVirologyCoreFormType.java | 56 ++++ .../genotypesWithSignificance.query.xml | 12 + .../genotypesWithSignificance.sql | 8 + .../schemas/GeneticTesting.template.xml | 12 + 31 files changed, 1317 insertions(+) create mode 100644 GeneticsCore/resources/schemas/dbscripts/postgresql/geneticscore-17.10-17.11.sql create mode 100644 GeneticsCore/resources/schemas/dbscripts/sqlserver/geneticscore-17.10-17.11.sql create mode 100644 ONPRC_EHR_ComplianceDB/module.properties create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/begin.html create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/begin.view.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/begin.webpart.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.view.xml create mode 100644 extscheduler/resources/queries/extscheduler/SchedulerAliases.sql create mode 100644 extscheduler/resources/queries/extscheduler/SchedulerAliases/.qview.xml create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.28-15.29.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.29-15.30.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.30-15.31.sql create mode 100644 onprc_billing/resources/etls/rateChangeUpdate.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/MiscChargesNotBilled_Virology.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/virologyAliases.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/virologyBillingCharges.sql create mode 100644 onprc_billing/resources/queries/virologyAliases.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-12.380-12.381.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.410-17.411.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.411-17.412.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.412-17.413.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.501-17.502.sql create mode 100644 onprc_billing/resources/web/onprc_billing/model/sources/AliasMisc.js create mode 100644 onprc_billing/resources/web/onprc_billing/model/sources/VirologyMisc.js create mode 100644 onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java create mode 100644 onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java create mode 100644 onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.query.xml create mode 100644 onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.sql create mode 100644 onprc_reports/resources/schemas/GeneticTesting.template.xml diff --git a/GeneticsCore/resources/schemas/dbscripts/postgresql/geneticscore-17.10-17.11.sql b/GeneticsCore/resources/schemas/dbscripts/postgresql/geneticscore-17.10-17.11.sql new file mode 100644 index 000000000..f3a6a3455 --- /dev/null +++ b/GeneticsCore/resources/schemas/dbscripts/postgresql/geneticscore-17.10-17.11.sql @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +CREATE TABLE geneticscore.taqman_probes ( + rowid serial, + probe varchar(100), + target varchar(1000), + + container ENTITYID, + created TIMESTAMP, + createdby USERID, + modified TIMESTAMP, + modifiedby USERID, + + CONSTRAINT PK_taqman_probes PRIMARY KEY (rowid) +); + +CREATE TABLE geneticscore.test_significance ( + rowid serial, + probe varchar(100), + genotype varchar(100), + label varchar(1000), + comment varchar(4000), + + container ENTITYID, + created TIMESTAMP, + createdby USERID, + modified TIMESTAMP, + modifiedby USERID, + + CONSTRAINT PK_test_significance PRIMARY KEY (rowid) +); \ No newline at end of file diff --git a/GeneticsCore/resources/schemas/dbscripts/sqlserver/geneticscore-17.10-17.11.sql b/GeneticsCore/resources/schemas/dbscripts/sqlserver/geneticscore-17.10-17.11.sql new file mode 100644 index 000000000..1dd7283be --- /dev/null +++ b/GeneticsCore/resources/schemas/dbscripts/sqlserver/geneticscore-17.10-17.11.sql @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +CREATE TABLE geneticscore.taqman_probes ( + rowid int identity(1,1), + probe varchar(100), + target varchar(1000), + + container ENTITYID, + created DATETIME, + createdby USERID, + modified DATETIME, + modifiedby USERID, + + CONSTRAINT PK_taqman_probes PRIMARY KEY (rowid) +); + +CREATE TABLE geneticscore.test_significance ( + rowid int identity(1,1), + probe varchar(100), + genotype varchar(100), + label varchar(1000), + comment varchar(4000), + + container ENTITYID, + created DATETIME, + createdby USERID, + modified DATETIME, + modifiedby USERID, + + CONSTRAINT PK_test_significance PRIMARY KEY (rowid) +); \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/module.properties b/ONPRC_EHR_ComplianceDB/module.properties new file mode 100644 index 000000000..6e371674a --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/module.properties @@ -0,0 +1,4 @@ +Name: ONPRC_EHR_ComplianceDB +ModuleClass: org.labkey.api.module.SimpleModule +ModuleDependencies: EHR_ComplianceDB +Version: 1.1 \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/begin.html b/ONPRC_EHR_ComplianceDB/resources/views/begin.html new file mode 100644 index 000000000..199940a0c --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/begin.html @@ -0,0 +1,72 @@ + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/begin.view.xml b/ONPRC_EHR_ComplianceDB/resources/views/begin.view.xml new file mode 100644 index 000000000..a01fb3cf0 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/begin.view.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/begin.webpart.xml b/ONPRC_EHR_ComplianceDB/resources/views/begin.webpart.xml new file mode 100644 index 000000000..bd3430562 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/begin.webpart.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html new file mode 100644 index 000000000..50dc0cd86 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html @@ -0,0 +1,266 @@ + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.view.xml b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.view.xml new file mode 100644 index 000000000..171801594 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/extscheduler/resources/queries/extscheduler/SchedulerAliases.sql b/extscheduler/resources/queries/extscheduler/SchedulerAliases.sql new file mode 100644 index 000000000..ed10d5b3f --- /dev/null +++ b/extscheduler/resources/queries/extscheduler/SchedulerAliases.sql @@ -0,0 +1,10 @@ +SELECT +a.ResourceId, +a.Name, +a.StartDate, +a.EndDate, +a.UserId, +a.Alias +FROM Events a +WHERE a.alias NOT IN (Select b.alias FROM "/onprc/admin/finance/public".onprc_billing_public.aliases b) +--AND a.alias IS NOT NULL \ No newline at end of file diff --git a/extscheduler/resources/queries/extscheduler/SchedulerAliases/.qview.xml b/extscheduler/resources/queries/extscheduler/SchedulerAliases/.qview.xml new file mode 100644 index 000000000..f5134953c --- /dev/null +++ b/extscheduler/resources/queries/extscheduler/SchedulerAliases/.qview.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.28-15.29.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.28-15.29.sql new file mode 100644 index 000000000..4ae71d86e --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.28-15.29.sql @@ -0,0 +1 @@ +ALTER TABLE extscheduler.Events ADD Quantity INT; \ No newline at end of file diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.29-15.30.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.29-15.30.sql new file mode 100644 index 000000000..6fc9496ad --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.29-15.30.sql @@ -0,0 +1 @@ +ALTER TABLE extscheduler.Events ADD Comments VARCHAR(255); \ No newline at end of file diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.30-15.31.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.30-15.31.sql new file mode 100644 index 000000000..048fef129 --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-15.30-15.31.sql @@ -0,0 +1,21 @@ + +ALTER TRIGGER extscheduler.TR_OverlappingDateRanges ON extscheduler.Events FOR INSERT, UPDATE AS +BEGIN + IF EXISTS( + SELECT 1 FROM extscheduler.events R + LEFT JOIN ( + SELECT ObjectId, Value FROM prop.Properties + JOIN prop.PropertySets ON PropertySets."Set" = Properties."Set" + WHERE Name = 'ExtSchedulerAllowEventOverlap' + ) P ON R.Container = P.ObjectId + INNER JOIN inserted I + ON (P.Value IS NULL OR P.Value = 'false') AND ( + (R.Container = I.Container AND R.ResourceId = I.ResourceId AND R.StartDate < I.EndDate AND I.StartDate < R.EndDate) + AND NOT (R.Id = I.Id) + ) + ) + BEGIN + RAISERROR('Start/End date ranges may not overlap for the same resource.', 16, 1) + ROLLBACK + END +END \ No newline at end of file diff --git a/onprc_billing/resources/etls/rateChangeUpdate.xml b/onprc_billing/resources/etls/rateChangeUpdate.xml new file mode 100644 index 000000000..7de179347 --- /dev/null +++ b/onprc_billing/resources/etls/rateChangeUpdate.xml @@ -0,0 +1,27 @@ + + + + + ratechangeUpdate + + Updates the Rate Sheets for Investigators in the Billing Public Folder + + + + + Runs a stored procedure to update the Rate Sheet for Public Rate Projections. + + + + + + + + + + + + + + + diff --git a/onprc_billing/resources/queries/onprc_billing/MiscChargesNotBilled_Virology.sql b/onprc_billing/resources/queries/onprc_billing/MiscChargesNotBilled_Virology.sql new file mode 100644 index 000000000..3280c65e3 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/MiscChargesNotBilled_Virology.sql @@ -0,0 +1,49 @@ +--New query as source of Misc CHarges Not yet billing will replace needed items in Test and Production +SELECT d.Id, +d.date, +d.billingDate, +d.project, +d.account as ChargeTo, +d.chargetype as CreditTo, +d.creditAccount, +d.creditAccountType, +d.investigatorId, +d.chargeId, +d.category, +d.item, +d.unitCost, +m.unitCost as nihRate, +d.quantity, +Sum(d.unitCost * d.quantity) as TOtalCharges, +d.chargeCategory, +d.comment, + +d.invoiceId, +d.created, +d.createdby, +m.taskId +FROM MiscChargeswithRates d join MiscCharges m on d.taskId = m.taskId and d.sourceRecord = m.objectID +where d.invoiceID is null and d.category = 'Virology' +Group by +d.Id, +d.date, +d.billingDate, +d.project, +d.account, +d.chargetype, +d.creditAccount, +d.creditAccountType, +d.investigatorId, +d.chargeId, +d.category, +d.item, +d.unitCost, +m.unitCost, +d.quantity, +d.chargeCategory, +d.comment, + +d.invoiceId, +d.created, +d.createdby, +m.taskId \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml b/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml new file mode 100644 index 000000000..387047268 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml @@ -0,0 +1,123 @@ + + + + + Manually Entered Charges + org.labkey.ehr.table.DefaultEHRCustomizer + + + + ehr + project + project + + + + Alias + + onprc_billing_public + aliases + alias + + /query/executeQuery.view?schemaName=onprc_billing_public&query.queryName=aliases&query.alias~eq=${account} + + + Investigator + true + + onprc_ehr + investigators + rowid + lastName + + + + + ehr + tasks + taskid + rowid + + + + Charge + + onprc_billing_public + chargeableItems + rowid + + + + Is Rate Exemption? + + + Unit Cost + $###,##0.00 + + + Total Cost + $###,##0.00 + + + Credit Alias + + + true + + + Assigned To Project On This Date? + + + Lacks Unit Cost? + + + Rate Id + /query/executeQuery.view?schemaName=onprc_billing&query.queryName=chargeRates&query.rowid~eq=${rateid} + + + Exemption Id + /query/executeQuery.view?schemaName=onprc_billing&query.queryName=chargeRateExemptions&query.rowid~eq=${exemptionId} + + + true + + + true + + + true + true + + + Missing Alias? + + + Missing FAID? + + + Expired Alias? + + + Alias Accepting Charges? + + + Is Adjustment/Reversal? + + + true + + + Alias Differs From Project? + + + >45 Days Old? + + + Is Manually Entered? + true + + +
+
+
+
\ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql b/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql new file mode 100644 index 000000000..bc8c7d915 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql @@ -0,0 +1,7 @@ +SELECT alias, alias + ' - ' + COALESCE(investigatorName, 'N/A') as aliasPI +FROM "/onprc/admin/finance/public".onprc_billing_public.aliases +--WHERE a.projectStatus in ('Active', 'Partial Setup', 'No Cost Ext', 'Preaward') OR a.alias in ('68119000', '46050050') +WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate > now() )) OR alias in ('68119000', '46050050','46030010', '61247550') +--Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')} +--WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate > now() )) +--OR alias in (Select alias from Special_Aliases Where category like 'Virology') diff --git a/onprc_billing/resources/queries/onprc_billing/virologyBillingCharges.sql b/onprc_billing/resources/queries/onprc_billing/virologyBillingCharges.sql new file mode 100644 index 000000000..b94348e6a --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/virologyBillingCharges.sql @@ -0,0 +1,4 @@ +SELECT rowid, category, activeRate.unitCost, itemCode + ' - ' + name as chargeName +FROM "/onprc/admin/finance/public".onprc_billing_public.chargeableItems +WHERE category = 'Virology' +AND Active = 'true' \ No newline at end of file diff --git a/onprc_billing/resources/queries/virologyAliases.sql b/onprc_billing/resources/queries/virologyAliases.sql new file mode 100644 index 000000000..f8ec6e8ea --- /dev/null +++ b/onprc_billing/resources/queries/virologyAliases.sql @@ -0,0 +1,3 @@ +SELECT rowid,aliases.alias, aliases.alias + ' - ' + aliases.investigatorName as aliasPI +FROM aliases +WHERE projectStatus = 'Active' \ No newline at end of file diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-12.380-12.381.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-12.380-12.381.sql new file mode 100644 index 000000000..ae4758524 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-12.380-12.381.sql @@ -0,0 +1,13 @@ +-- Created: 4-26-2017 R.Blasa + +CREATE TABLE onprc_billing.MergeChargtypeUpdates ( + rowid int IDENTITY(1,1) NOT NULL, + ProjectName varchar(50) not null, + Protocol varchar(100) not null, + ChargeType varchar(50) not null, + objectid ENTITYID, + startDate datetime, + endDate datetime + +CONSTRAINT PK_MergeType PRIMARY KEY(rowid) +); \ No newline at end of file diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.410-17.411.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.410-17.411.sql new file mode 100644 index 000000000..9c8dcc3cc --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.410-17.411.sql @@ -0,0 +1,23 @@ +-- Adds table Annual Rate Change to Billing +-- Note: Unnecessary due to onprc_billing.AnnualRateChange existing in the DB +-- from when it was renamed in the 12.378-12.379 script + + +-- SET ANSI_NULLS ON +-- GO +-- +-- SET QUOTED_IDENTIFIER ON +-- GO +-- DROP TABLE onprc_billing.AnnualRateChange; +-- CREATE TABLE onprc_billing.AnnualRateChange +-- ( +-- [billingYear] [varchar](10) NOT NULL, +-- [inflationRate] [decimal](18, 0) NULL, +-- [startDate] [datetime] NULL, +-- [endDate] [datetime] NULL, +-- [createdBy] [int] NULL, +-- [created] [datetime] NULL, +-- [modifiedBy] [int] NULL, +-- [modified] [datetime] NULL +-- ) ON [PRIMARY] +-- GO \ No newline at end of file diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.411-17.412.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.411-17.412.sql new file mode 100644 index 000000000..69f8af00e --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.411-17.412.sql @@ -0,0 +1,4 @@ +-- Adds table Annual Rate Change to Billing +-- add primary key and identity key +ALTER TABLE onprc_billing.AnnualRateChange Add RowID Int IDENTITY (1,1)not null; +ALTER TABLE onprc_billing.AnnualRateChange Add CONSTRAINT PK_AnnualRateChange_RowID PRIMARY KEY CLUSTERED (RowID); diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.412-17.413.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.412-17.413.sql new file mode 100644 index 000000000..2d590f568 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.412-17.413.sql @@ -0,0 +1,4 @@ +-- Adds change inflation rate to 3 position decimal +-- add primary key and identity key +alter table [onprc_billing].[AnnualRateChange] +ALTER COLUMN InflationRate Numeric(18,4) \ No newline at end of file diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.501-17.502.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.501-17.502.sql new file mode 100644 index 000000000..e019a7fbe --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-17.501-17.502.sql @@ -0,0 +1,285 @@ + +GO +/****** Object: StoredProcedure [onprc_billing].[AnnualRateChangeProcess] Script Date: 5/4/2018 10:50:22 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ============================================= +-- Author: +-- Create date: +-- Description: +-- ============================================= + +--DROP Procedure [onprc_billing].[AnnualRateChange] +--Go + +CREATE Procedure [onprc_billing].[AnnualRateChangeProcess] + +AS + +BEGIN +DECLARE + + + @Year1 float, + @Year2 float, + @Year3 float, + @Year4 float, + @Year5 float, + @Year6 float, + @Year7 float, + @Year8 float, + @Year9 float, + @Aprate1 float, + @Aprate2 float, + @Aprate3 float, + @Aprate4 float, + @Aprate5 float, + @Aprate6 float, + @Aprate7 float, + @Aprate8 float, + @Aprate9 float, + + @UnitCost float, + @nSearchkey int, + @TempSearchkey Int, + @ChargeId SmallInt, + @CurrentBillingYear SmallInt, + @Billingyear as Smallint + + + + + + + + + ---- Reset Temp tables + + Delete Rpt_ChargesProjection + + + + + ----- INitialize variables + + Set @nSearchkey = 0 + Set @TempSearchkey = 0 + Set @Aprate1 = 0 + Set @Aprate2 = 0 + Set @Aprate3 = 0 + Set @Aprate4 = 0 + Set @Aprate5 = 0 + Set @Aprate6 = 0 + Set @Aprate7 = 0 + Set @Aprate8 = 0 + Set @Aprate9 = 0 + SET @CurrentBillingYear = (Select DATEDIFF(Year,'5/1/1959',GetDate())) + SET @Billingyear = @CurrentBillingYear + 1 + + + + ---- Begin Processing Data + + select Top 1 @nSearchkey = rowid from onprc_billing.chargeRates + where endDate >= GETDATE() + order by rowid + + + + --Billing Year Constant + + + + Select @Aprate1 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + + Select @Aprate2 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 1 + + Select @Aprate3 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 2 + + If exists (Select InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 3) + Begin + + Select @Aprate4 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 3 + End + + + + If exists (Select InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 4) + Begin + + Select @Aprate5 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 4 + End + + If exists (Select InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 5) + Begin + + Select @Aprate6 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 5 + + End + + If exists (Select InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 6) + Begin + + Select @Aprate7 = InflationRate from onprc_billing.AnnualRateChange + Where Billingyear = @BillingYear + 6 + + End + + If exists (Select InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 7) + Begin + + Select @Aprate8 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 7 + + End + + + If exists (Select InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 8) + Begin + + Select @Aprate9 = InflationRate from onprc_billing.AnnualRateChange + + Where Billingyear = @BillingYear + 8 + End + + + + While @TempSearchKey < @nSearchkey + Begin + + Set @Year1 = 0.0 + Set @Year2 = 0.0 + Set @Year3 = 0.0 + Set @Year4 = 0.0 + Set @Year5 = 0.0 + Set @Year6 = 0.0 + Set @Year7 = 0.0 + Set @Year8 = 0.0 + Set @Year9 = 0.0 + Set @UnitCost = 0.0 + Set @ChargeId = 0 + + If exists(select * from onprc_billing.chargeRates + where endDate >= GETDATE() + And rowid = @nSearchkey) + BEgin + + select Top 1 @UnitCost = unitcost, @ChargeId = chargeid from onprc_billing.chargeRates + where endDate >= GETDATE() + and rowid = @nSearchkey + order by rowid + + + + set @Year1 = @Aprate1 * @UnitCost + Set @year2 = @year1 * @Aprate2 + Set @Year3 = @year2 * @Aprate3 + Set @Year4 = @year3 * @Aprate4 + Set @Year5 = @year4 * @Aprate5 + Set @Year6 = @year5 * @Aprate6 + Set @Year7 = @year6 * @Aprate7 + Set @Year8 = @year7 * @Aprate8 + Set @Year9 = @year8 * @Aprate9 + + + + Insert into Rpt_ChargesProjection + values( + @ChargeId, ------- ChargeId + @UnitCost, ---- starting unit cost for the project year + @Year1, ----- !st Rate computation + @Year2, ----- !st Rate computation + @Year3, ----- !st Rate computation + @Year4, ----- !st Rate computation + @Year5, ----- !st Rate computation + @Year6, ----- !st Rate computation + @Year7, ----- !st Rate computation + @Year8, ----- !st Rate computation + -- @Year9, ----- !st Rate computation, + @Aprate1, ------ inflation rate year 57 + @Aprate2, ------ inflation rate year 58 + @Aprate3, ------ inflation rate year 59 + @Aprate4, ------ inflation rate year 60 + @Aprate5, ------ inflation rate year 61 + @Aprate6, ------ inflation rate year 62 + @Aprate7, ------ inflation rate year 63 + @Aprate8, ------ inflation rate year 64 + @Aprate9, ------ inflation rate year 65 + @nSearchkey, ---- RowID + getdate() ---- run date + + ) + + End ---(if) + + + Set @TempSearchKey = @nSearchkey + + + select Top 1 @nSearchkey = rowid from onprc_billing.chargeRates + where endDate >= GETDATE() + And rowid > @nSearchkey + order by rowid + + + + + End ----(While) + + + + ---Now display the results of the computation + Select chargeid as [ChargeID], + unitcost as [UnitCost], + Year1, + Year2, + Year3, + Year4, + Year5, + Year6, + Year7, + Year8, + -- year9, + Rowid as [Row ID], + posteddate as [PostedDate] + + + from Rpt_ChargesProjection + + Order by chargeid + + + + + + + + +END diff --git a/onprc_billing/resources/web/onprc_billing/model/sources/AliasMisc.js b/onprc_billing/resources/web/onprc_billing/model/sources/AliasMisc.js new file mode 100644 index 000000000..377327207 --- /dev/null +++ b/onprc_billing/resources/web/onprc_billing/model/sources/AliasMisc.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +//Created: 6-8-2017 R.Blasa +EHR.model.DataModelManager.registerMetadata('AliasMisc', { + allQueries: { + }, + byQuery: { + 'onprc_billing.miscCharges': { + debitedaccount: { + xtype: 'textfield', + header: 'Alias', + width: 200, + hidden: false + }, + project: { + allowBlank: true + } + } + } +}); \ No newline at end of file diff --git a/onprc_billing/resources/web/onprc_billing/model/sources/VirologyMisc.js b/onprc_billing/resources/web/onprc_billing/model/sources/VirologyMisc.js new file mode 100644 index 000000000..5c0797b56 --- /dev/null +++ b/onprc_billing/resources/web/onprc_billing/model/sources/VirologyMisc.js @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + + +EHR.model.DataModelManager.registerMetadata('VirologyMisc', { + allQueries: { + }, + byQuery: { + 'onprc_billing.miscCharges': { + Id: { + hidden: false, + header: 'Animal Id' + }, + + chargeId: { + xtype: 'combo', + header: 'Charge Name', + hidden: false, + lookup: { + schemaName: 'onprc_billing', + queryName: 'virologyBillingCharges', + displayColumn: 'chargeName', + keyColumn: 'rowid', + columns: 'rowid, category, chargeName, unitCost' + }, + editorConfig: { + listConfig: { + //innerTpl: '{[(values.category ? "" + values.category + ": " : "") + values.chargeName]}', + innerTpl: '{[("" + values.chargeName + "" )]}', + getInnerTpl: function(){ + return this.innerTpl; + } + } + }, + columnConfig: { + width: 400 + } + + }, + + debitedaccount: { + xtype: 'combo', + header: 'Alias', + hidden: false, + lookup: { + schemaName: 'onprc_billing', + queryName: 'virologyAliases', + displayColumn: 'aliasPI', + keyColumn: 'alias', + columns: 'alias, aliasPI' + }, + editorConfig: { + listConfig: { + innerTpl: '{[("" + values.aliasPI + "" )]}', + getInnerTpl: function(){ + return this.innerTpl; + } + } + }, + columnConfig: { + width: 300 + } + + }, + + project: { + allowBlank: true, + hidden: true + }, + + comment: { + allowBlank: true, + columnConfig: { + width: 200 + } + }, + + unitcost: { + hidden: false, + header: 'NIH Rate', + editorConfig: { + decimalPrecision: 2 + } + }, + + lineItemTotal: { + allowBlank: true, + header: 'Estimated Charge', + nullable: true, + hidden: false, + shownInGrid: true, + columnConfig: { + width: 200 + } + }, + + chargetype: { + allowBlank: true, + defaultValue: 'Virology Core', + hidden: false + } + + } + } +}); \ No newline at end of file diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java new file mode 100644 index 000000000..1736e0ebb --- /dev/null +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_billing.dataentry; + +import org.labkey.api.data.TableInfo; +import org.labkey.api.ehr.EHRService; +import org.labkey.api.ehr.dataentry.SimpleFormSection; +import org.labkey.api.query.FieldKey; +import org.labkey.api.view.template.ClientDependency; + +import java.util.Collections; +import java.util.List; + + +public class ChargesVirologyCoreFormSection extends SimpleFormSection +{ + public ChargesVirologyCoreFormSection() + { + this(EHRService.FORM_SECTION_LOCATION.Body); + } + + public ChargesVirologyCoreFormSection(EHRService.FORM_SECTION_LOCATION location) + { + super("onprc_billing", "miscCharges", "Virology Charges", "ehr-gridpanel", location); + //super("onprc_billing", "virologyCharges", "Virology Charges", "ehr-gridpanel", location); + setConfigSources(Collections.singletonList("Task")); + setClientStoreClass("EHR.data.MiscChargesClientStore"); + addClientDependency(ClientDependency.fromPath("ehr/data/MiscChargesClientStore.js")); + +// setClientStoreClass("EHR.data.VirologyChargesClientStore"); +// addClientDependency(ClientDependency.fromPath("ehr/data/VirologyChargesClientStore.js")); + + addClientDependency(ClientDependency.fromPath("onprc_billing/model/sources/VirologyMisc.js")); + addConfigSource("VirologyMisc"); + } + + @Override + protected List getFieldKeys(TableInfo ti) + { + List result = super.getFieldKeys(ti); + + result.add(10,FieldKey.fromParts("lineItemTotal")); + return result; + } +} + + diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java new file mode 100644 index 000000000..a5a4632d3 --- /dev/null +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java @@ -0,0 +1,56 @@ +package org.labkey.onprc_billing.dataentry; + +import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.TaskForm; +import org.labkey.api.ehr.dataentry.TaskFormSection; +import org.labkey.api.module.Module; +import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.permissions.AdminPermission; +import org.labkey.api.security.Group; + +import java.util.Arrays; +import java.util.List; + + +public class ChargesVirologyCoreFormType extends TaskForm +{ + public static final String NAME = "VirologyCoreCharges"; + + public ChargesVirologyCoreFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "Virology Charges", "Billing - Virology Core", Arrays.asList( + new TaskFormSection(), +// new AnimalDetailsFormSection(), + new ChargesInstructionFormSection(), + new ChargesVirologyCoreFormSection() + )); + + addClientDependency(ClientDependency.fromPath("onprc_billing/panel/ChargesInstructionPanel.js")); + } + + + //Added: 11/1/2018 R.Blasa Hide this menu when SLA users are accessing their exit records + @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "SLA Users", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + return super.isVisible(); + } + + @Override + protected List getMoreActionButtonConfigs() + { + List defaultButtons = super.getMoreActionButtonConfigs(); + defaultButtons.add("COPY_TASK"); + + return defaultButtons; + } +} diff --git a/onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.query.xml b/onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.query.xml new file mode 100644 index 000000000..5fa2cc95d --- /dev/null +++ b/onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.query.xml @@ -0,0 +1,12 @@ + + + + + Genetic Tests + + + +
+
+
+
diff --git a/onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.sql b/onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.sql new file mode 100644 index 000000000..0b7d213db --- /dev/null +++ b/onprc_reports/resources/queries/genotypeassays/genotypesWithSignificance.sql @@ -0,0 +1,8 @@ +SELECT +d.subjectId as Id, +d.date, +t.label, +t.comment + +FROM assay.SSP_Assay.TaqMan.data d +JOIN geneticscore.test_significance t ON (d.primerPair = t.probe AND d.result = t.genotype) \ No newline at end of file diff --git a/onprc_reports/resources/schemas/GeneticTesting.template.xml b/onprc_reports/resources/schemas/GeneticTesting.template.xml new file mode 100644 index 000000000..9c3e690f2 --- /dev/null +++ b/onprc_reports/resources/schemas/GeneticTesting.template.xml @@ -0,0 +1,12 @@ + + + genotypesWithSignificance + + + + + + + + + \ No newline at end of file From 6a0c64bbdab45329e052a028cd2a9826441f2bce Mon Sep 17 00:00:00 2001 From: Binal Date: Tue, 6 Oct 2020 14:28:13 -0700 Subject: [PATCH 03/49] Merge from onprc19.1 r.63282 --- .../queries/onprc_billing/labworkFees.sql | 28 +- onprc_ehr/resources/etls/AvailableBlood.xml | 2 +- .../Flag_Categories_Active.query.xml | 14 + .../ehr_lookups/Flag_Categories_Active.sql | 3 + .../queries/onprc_ehr/NHP_Training.js | 4 + .../queries/onprc_ehr/NHP_Training.query.xml | 64 +++ .../queries/onprc_ehr/NHP_Training/.qview.xml | 12 + .../onprc_ehr/vet_assignment_summary.sql | 26 +- .../queries/study/LastHousingLocation.sql | 23 ++ ...sueDistributionSummaryCalendarYr.query.xml | 20 + .../TissueDistributionSummaryCalendarYr.sql | 11 + .../.qview.xml | 6 + ...tionSummarybyRecipientCalendarYr.query.xml | 20 + ...stributionSummarybyRecipientCalendarYr.sql | 13 + .../.qview.xml | 6 + .../queries/study/demographicsAssignedVet.sql | 192 ++++----- .../queries/study/hematologyPivot.sql | 2 +- .../study/mostRecentObservationsBehavior.sql | 2 +- .../All Behavior Cases.qview.xml | 27 ++ .../Open Behavior Case.qview.xml | 3 + .../study/vet_assignmentDemographics.sql | 82 ++++ .../queries/study/vet_assignmentselect.sql | 54 +++ .../scripts/onprc_ehr/onprc_triggers.js | 97 ++++- onprc_ehr/resources/views/begin.html | 4 +- onprc_ehr/resources/views/citesReport.html | 4 +- onprc_ehr/resources/views/historyExport.html | 4 +- .../resources/views/printableReports.html | 18 +- .../web/onprc_ehr/DemographicsRecord.js | 5 + .../web/onprc_ehr/buttons/pathologyButtons.js | 15 + .../onprc_ehr/data/sources/ONPRCDefaults.js | 21 + .../onprc_ehr/model/sources/Gross_Finding.css | 5 +- .../web/onprc_ehr/panel/AnimalDetailsPanel.js | 265 ++++++++++++ .../web/onprc_ehr/panel/SnapshotPanel.js | 65 +++ .../window/CreateTaskFromRecordsWindow.js | 377 ++++++++++++++++++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 23 +- .../buttons/CreateTaskFromRecordButtons.java | 53 +++ .../dataentry/AnimalDetailssFormSection.java | 31 ++ .../dataentry/LabworkRequestFormType.java | 5 +- .../onprc_ehr/dataentry/NecropsyFormType.java | 3 +- .../PathologyDiagnosesFormSection.java | 11 + .../LastHousingDemographicsProvider.java | 55 +++ .../InfantsBornAssignedNotification.java | 2 +- .../TreatmentAlertsPostOpsNotification.java | 8 +- .../query/ONPRC_EHRTriggerHelper.java | 29 ++ sla/resources/queries/sla/PlandProtocols.sql | 3 + .../queries/sla/ProtocolProjectsUsage.sql | 85 +++- .../web/sla/form/CreatePurchaseOrder.js | 71 ++-- .../queries/study/treatmentScheduleUpdate.sql | 5 + 48 files changed, 1666 insertions(+), 212 deletions(-) create mode 100644 onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.query.xml create mode 100644 onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NHP_Training.js create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NHP_Training.query.xml create mode 100644 onprc_ehr/resources/queries/study/LastHousingLocation.sql create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.sql create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.sql create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/All Behavior Cases.qview.xml create mode 100644 onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql create mode 100644 onprc_ehr/resources/queries/study/vet_assignmentselect.sql create mode 100644 onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsPanel.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/CreateTaskFromRecordsWindow.js create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/demographics/LastHousingDemographicsProvider.java diff --git a/onprc_billing/resources/queries/onprc_billing/labworkFees.sql b/onprc_billing/resources/queries/onprc_billing/labworkFees.sql index 487ebcd57..b1c222f8a 100644 --- a/onprc_billing/resources/queries/onprc_billing/labworkFees.sql +++ b/onprc_billing/resources/queries/onprc_billing/labworkFees.sql @@ -1,28 +1,20 @@ -/* - * Copyright (c) 2013 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ ---this query displays all animals co-housed with each housing record ---to be considered co-housed, they only need to overlap by any period of time - PARAMETERS(StartDate TIMESTAMP, EndDate TIMESTAMP) SELECT e.Id, e.date, - e.datefinalized as billingDate, + e.billingDate, e.project, e.servicerequested, p.chargeId, - e.objectid as sourceRecord, + e.sourceRecord, null as chargeCategory, e.taskid -FROM study.clinpathRuns e +FROM onprc_billing.clinPathRun_ExemptCharges e JOIN onprc_billing.labworkFeeDefinition p ON (p.servicename = e.servicerequested AND p.active = true) -WHERE CAST(e.datefinalized as date) >= CAST(StartDate as date) AND CAST(e.datefinalized as date) <= CAST(EndDate as date) +WHERE CAST(e.billingdate as date) >= CAST(StartDate as date) AND CAST(e.billingdate as date) <= CAST(EndDate as date) AND (e.chargetype not in ('Not Billable', 'No Charge', 'Research Staff') or e.chargetype is null) AND e.qcstate.publicdata = true @@ -31,18 +23,18 @@ UNION ALL --for any service sent to an outside lab, we have 1 processing charge per distinct sample SELECT e.Id, - e.dateOnly, - e.datefinalized as billingDate, + e.date, + e.billingDate, e.project, group_concat(e.servicerequested) as servicerequested, - (SELECT c.rowid FROM onprc_billing_public.chargeableItems c WHERE c.name = 'Lab Processing Fee') as chargeId, + (SELECT c.rowid FROM onprc_billing_public.chargeableItems c WHERE c.name = 'Lab Processing Fee') as chargeId, null as sourceRecord, null as chargeCategory, e.taskid -FROM study.clinpathRuns e -WHERE CAST(e.datefinalized as date) >= CAST(StartDate as date) AND CAST(e.datefinalized as date) <= CAST(EndDate as date) +FROM onprc_billing.clinPathRun_ExemptCharges e +WHERE CAST(e.billingDate as date) >= CAST(StartDate as date) AND CAST(e.billingDate as date) <= CAST(EndDate as date) AND e.qcstate.publicdata = true AND (e.chargetype not in ('Not Billable', 'No Charge', 'Research Staff') or e.chargetype is null) AND e.servicerequested.outsidelab = true -GROUP BY e.Id, e.dateOnly, e.datefinalized, e.project, e.tissue, e.taskid \ No newline at end of file +GROUP BY e.Id, e.date, e.billingdate, e.project, e.tissue, e.taskid \ No newline at end of file diff --git a/onprc_ehr/resources/etls/AvailableBlood.xml b/onprc_ehr/resources/etls/AvailableBlood.xml index 21a46893f..7cadfb985 100644 --- a/onprc_ehr/resources/etls/AvailableBlood.xml +++ b/onprc_ehr/resources/etls/AvailableBlood.xml @@ -24,7 +24,7 @@ - + diff --git a/onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.query.xml b/onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.query.xml new file mode 100644 index 000000000..0805b73f1 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.query.xml @@ -0,0 +1,14 @@ + + + + + Procedure Names + + + true + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.sql b/onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.sql new file mode 100644 index 000000000..aa9667660 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr_lookups/Flag_Categories_Active.sql @@ -0,0 +1,3 @@ + + +SELECT * FROM ehr_lookups.Flag_Categories Where datedisabled is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/NHP_Training.js b/onprc_ehr/resources/queries/onprc_ehr/NHP_Training.js new file mode 100644 index 000000000..9ee75ca8f --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NHP_Training.js @@ -0,0 +1,4 @@ + +//Created: 1-31-2019 R.Blasa NHP_Training input screen triggers + +require("ehr/triggers").initScript(this); diff --git a/onprc_ehr/resources/queries/onprc_ehr/NHP_Training.query.xml b/onprc_ehr/resources/queries/onprc_ehr/NHP_Training.query.xml new file mode 100644 index 000000000..741a2af88 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NHP_Training.query.xml @@ -0,0 +1,64 @@ + + + + + NHP Training + DETAILED + + + + true + + + + Id + /ehr/participantView.view?participantId=${Id} + + + + Start Date + + + + End Date + + + Training Type + + + true + + + true + + + + Training Reason + + + Training Result + + + + + study + qcstate + RowId + + + + + Task Id + + ehr + tasks + taskid + + + + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/onprc_ehr/NHP_Training/.qview.xml b/onprc_ehr/resources/queries/onprc_ehr/NHP_Training/.qview.xml index 952afc42f..4f18338ce 100644 --- a/onprc_ehr/resources/queries/onprc_ehr/NHP_Training/.qview.xml +++ b/onprc_ehr/resources/queries/onprc_ehr/NHP_Training/.qview.xml @@ -39,6 +39,18 @@
+ + + + + + + + + + + + diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.sql b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.sql index 1346ed6ae..7cb55de4e 100644 --- a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.sql +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.sql @@ -13,11 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Updated 2019-01-26 + * revied to allow assigned of vet by Protocol and Room or Protocol and Area + */ SELECT v.userId, - group_concat(DISTINCT (v.area || CASE WHEN v.priority = true THEN '*' ELSE '' END), chr(10)) as areas, + + group_concat(DISTINCT ( CASE WHEN (v.protocol is not null and v.room is not null) THEN (v.protocol.displayname || '-' || v.room) ELSE '' END), chr(10)) as Protocol_Room, + group_concat(DISTINCT ( CASE WHEN (v.protocol is not null and v.area is not null) THEN (v.protocol.displayname || '-' || v.area) ELSE '' END), chr(10)) as Protocol_Area, + group_concat(DISTINCT (v.protocol.displayName || ' (' || v.protocol.investigatorid.lastname || ')'), chr(10)) as protocols, group_concat(DISTINCT (v.room || CASE WHEN v.priority = true THEN '*' ELSE '' END), chr(10)) as rooms, - group_concat(DISTINCT (v.protocol.displayName || ' (' || v.protocol.investigatorid.lastname || ')'), chr(10)) as protocols + group_concat(DISTINCT (v.area || CASE WHEN v.priority = true THEN '*' ELSE '' END), chr(10)) as areas + + FROM onprc_ehr.vet_assignment v GROUP BY v.userId \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/LastHousingLocation.sql b/onprc_ehr/resources/queries/study/LastHousingLocation.sql new file mode 100644 index 000000000..22ba636e6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/LastHousingLocation.sql @@ -0,0 +1,23 @@ + +/* + * Copyright (c) 2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +-- Created: 12-19-2018 R.Blasa + +select a.Id,(a.room + ' ' + coalesce(a.cage, '')) as location from study.housing a +where a.date in (Select max( b.date) from study.housing b + where a.Id = b.Id + and a.qcstate.publicdata = true ) diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml new file mode 100644 index 000000000..be13b4ba6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml @@ -0,0 +1,20 @@ + + + + + Tissue Distribution Summary + + + Total Samples + /query/executeQuery.view? + schemaName=study& + query.queryName=Tissue Distributions& + query.calendarYear~eq=${calendarYear}& + query.requestCategory~eq=${requestCategory}& + + + +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.sql b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.sql new file mode 100644 index 000000000..7df1aedd7 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.sql @@ -0,0 +1,11 @@ +-- Created: 1-2-2-18 R.Blasa +SELECT + calendarYear, + t.requestCategory, + count(t.Id) as totalSamples, + count(distinct t.Id) as distinctAnimals, + count(distinct t.recipient) as distinctRecipients + +FROM study.tissueDistributions t + +GROUP BY calendarYear, t.requestCategory \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr/.qview.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr/.qview.xml new file mode 100644 index 000000000..ad537ace4 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr/.qview.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml new file mode 100644 index 000000000..0ae656fcc --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml @@ -0,0 +1,20 @@ + + + + + Tissue Distribution Summary By Recipient + + + Total Samples + /query/executeQuery.view? + schemaName=study& + query.queryName=Tissue Distributions& + query.calendarYear~eq=${calendarYear}& + query.recipient~eq=${recipient}& + + + +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.sql b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.sql new file mode 100644 index 000000000..f6eed75eb --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.sql @@ -0,0 +1,13 @@ +-- Added: 1-2-2018 R.Blasa +SELECT + calendarYear, + t.recipient, + t.recipient.affiliation, + t.requestCategory, + count(t.Id) as totalSamples, + count(distinct t.Id) as distinctAnimals, + count(distinct t.recipient) as distinctRecipients, + +FROM study.tissueDistributions t + +GROUP BY calendarYear, t.recipient, t.recipient.affiliation, t.requestCategory \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr/.qview.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr/.qview.xml new file mode 100644 index 000000000..27d2df941 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr/.qview.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql index d7fe7474a..15e925a27 100644 --- a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql +++ b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql @@ -1,121 +1,71 @@ -/* - * Copyright (c) 2014-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -SELECT - d.Id, - COALESCE(n.assignedVet,c.vetNames, h.highPriRoomVetNames, h.highPriAreaVetNames, a1.vetName,a2.vetName, h.roomVetNames, h.areaVetNames) as assignedVet, - --COALESCE(c.vetUserIds, h.highPriRoomVetUserIds, h.highPriAreaVetUserIds, a.vetUserIds, h.roomVetUserIds, h.areaVetUserIds) as assignedVetId, - CASE - WHEN (n.status IS NOT null) THEN 'DECEASED NHP' - WHEN (c.vetNames IS NOT NULL) THEN 'Active Case' - WHEN (h.highPriRoomVetNames IS NOT NULL) THEN 'Room (Priority)' - WHEN (h.highPriAreaVetNames IS NOT NULL) THEN 'Area (Priority)' - WHEN (a1.vetName IS NOT NULL) THEN 'Research Assignment' - WHEN (a2.vetName IS NOT NULL) THEN 'Resource Assignment' - WHEN (h.roomVetNames IS NOT NULL) THEN 'Room' - WHEN (h.areaVetNames IS NOT NULL) THEN 'Area' - ELSE 'None' - END as assignmentType, - a1.protocol as ResearchProtocol, - a2.protocol as ResourceProtocol, - h.areas, - h.rooms - -FROM study.demographics d - -LEFT JOIN ( - Select - n.id, - vd.assignedVet, - 'Deceased' as status - from study.deaths n left outer join study.vetAssignedDeceased vd on n.Id = vd.id - -) - n on (n.Id =d.id) - -LEFT JOIN ( - SELECT - c.Id, - group_concat(distinct c.assignedvet.DisplayName) as vetNames, - CAST(group_concat(distinct c.assignedvet) as varchar(200)) as vetUserIds - FROM study.cases c - --WHERE c.isOpen = true - WHERE c.enddateCoalesced >= curdate() OR CAST(c.enddate AS DATE) = CAST(c.Id.demographics.lastDayAtCenter AS DATE) - GROUP BY c.Id -) c ON (c.Id = d.Id) - ---LEFT JOIN( ---Select cr.assignedVet ---from study.clinremarks cr) ---cr ON (cr.id = d.Id) --- ---need to insure we get the last record in Clinical Remarks for the animal. --- --- --- ---) - - -LEFT JOIN ( -Select a1.id, -a1.vetAssigned as vetName, -a1.protocol -from researchAssigned a1) -a1 ON (a1.Id = d.Id) - -LEFT JOIN ( -Select a2.id, -a2. vetAssigned as vetName, -a2.protocol -from resourceAssigned a2 ) -a2 ON (a2.Id = d.Id) - - - - --- SELECT --- a.Id, --- group_concat(distinct CAST(v.userId.displayName as varchar(120))) as vetNames, --- CAST(group_concat(distinct v.userId) as varchar(200)) as vetUserIds, --------- Need to only look at Vets on assignment as assigned vet for reseach protocols --- (Select distinct a2.project.protocol.displayname from study.assignment a2 where a2.project.protocol = v.protocol and a2.project.use_category.value = 'Research') as protocols ----- group_concat.use_cagte(distinct a.project.protocol.displayName) as protocols --- FROM study.assignment a --- JOIN onprc_ehr.vet_assignment v ON (a.project.protocol = v.protocol) --- WHERE a.enddateCoalesced >= curdate() OR CAST(a.enddateCoalesced AS DATE) = CAST(a.Id.demographics.lastDayAtCenter AS DATE) --- GROUP BY a.Id,v.protocol - - -LEFT JOIN ( - SELECT - h.Id, - group_concat(distinct CASE WHEN (v.area IS NOT NULL) THEN CAST(v.userId.displayName as varchar(120)) ELSE NULL END) as areaVetNames, - group_concat(distinct CASE WHEN (v.room IS NOT NULL) THEN CAST(v.userId.displayName as varchar(120)) ELSE NULL END) as roomVetNames, - group_concat(distinct CASE WHEN (v.area IS NOT NULL and v.priority = true) THEN CAST(v.userId.displayName as varchar(120)) ELSE NULL END) as highPriAreaVetNames, - group_concat(distinct CASE WHEN (v.room IS NOT NULL and v.priority = true) THEN CAST(v.userId.displayName as varchar(120)) ELSE NULL END) as highPriRoomVetNames, - - group_concat(distinct CASE WHEN (v.area IS NOT NULL) THEN v.userId ELSE NULL END) as areaVetUserIds, - group_concat(distinct CASE WHEN (v.room IS NOT NULL) THEN v.userId ELSE NULL END) as roomVetUserIds, - group_concat(distinct CASE WHEN (v.area IS NOT NULL and v.priority = true) THEN v.userId ELSE NULL END) as highPriAreaVetUserIds, - group_concat(distinct CASE WHEN (v.room IS NOT NULL and v.priority = true) THEN v.userId ELSE NULL END) as highPriRoomVetUserIds, - - group_concat(distinct h.room.area) as areas, - group_concat(distinct h.room) as rooms - - FROM study.housing h - JOIN onprc_ehr.vet_assignment v ON (v.area = h.room.area OR v.room = h.room) - WHERE h.enddateTimeCoalesced >= now() OR CAST(h.enddateCoalesced AS DATE) = CAST(h.Id.demographics.lastDayAtCenter AS DATE) - GROUP BY h.Id -) h ON (h.Id = d.Id) --Where d.calculated_status = 'alive' \ No newline at end of file +--Update 3/7/2019 load to test + +Select +Distinct +d.Id, +d.room.area as Area, +d.room, +d.CaseVet, +d.protocol, +Case + + when d.caseVet is not null then d.CaseVet + when p3.userId is not null then v1.userId.displayName + when p4.userId is not null then v2.userId.DisplayName + when v1.userId is not null then v1.userId.displayName + when v2.userId is not null then v2.userId.DisplayName + when v3.userId is not null then v3.userId.DisplayName + when v4.userId is not null then v4.userId.DisplayName + when p1.userId is not null then p1.userId.DisplayName + when p2.userId is not null then p2.userId.DisplayName + when v5.userId is not null then v5.userId.DisplayName + when v6.userId is not null then v6.userId.DisplayName + when h1.userId is not null then h1.userId.DisplayName + when h2.userId is not null then h2.userId.DisplayName + + End as AssignedVet, + +Case + + when d.caseVet is not null then 'Open Case' + When p3.userId is not null then 'Protocol Room Priority' + When p4.userId is not null then 'Protocol Area Priority' + when v1.userId is not null then 'Protocol Research Room' + when v2.userId is not null then 'Protocol Research Area' + when v3.userId is not null then 'Protocol Resource Room' + when v4.userId is not null then 'Protocol Resource Area' + when p1.userId is not null then 'Room Priority' + when p2.userId is not null then 'Area Priority' + when v5.userId is not null then 'Protocol Research Only' + when v6.userId is not null then 'Protocol Resource Only' + + when h1.userId is not null then 'Room Only' + when h2.userId is not null then 'Area Only' + + End as AssignmentType + +FROM study.vet_assignmentDemographics d +--this handles REsearch Protocol Room +Left Join onprc_ehr.vet_assignment v1 on (v1.protocol.displayName = d.protocol and v1.room = d.room and d.assignmentType = 'Research Assigned') +--this handles Research Protocol Area +Left Join onprc_ehr.vet_assignment v2 on (v2.protocol.displayName = d.protocol and v2.area = d.room.area and d.assignmentType = 'Research Assigned') +--this handles Resource Protocol Room +Left Join onprc_ehr.vet_assignment v3 on (v3.protocol.displayName = d.protocol and v3.room = d.room and d.assignmentType = 'Resource Assigned') +--this handles Research Protocol Area +Left Join onprc_ehr.vet_assignment v4 on (v4.protocol.displayName = d.protocol and v4.area = d.room.area and d.assignmentType = 'Resource Assigned') +--this handled Research Assigned No Additional Sekections +Left Join onprc_ehr.vet_assignment v5 on (v5.protocol.displayName = d.protocol and v5.room is null and v5.area is null and d.assignmentType = 'Research Assigned' ) +--this handles resource Protocol Only +Left Join onprc_ehr.vet_assignment v6 on (v6.protocol.displayName = d.protocol and v6.room is null and v6.area is null and d.assignmentType = 'Resource Assigned' ) +--this handles when the room is a priorty +Left join onprc_ehr.vet_assignment p1 on (p1.room = d.room and p1.protocol is null and p1.priority = true) +--this handles when the room is a priorty- +Left join onprc_ehr.vet_assignment p2 on (p2.area = d.room.area and p2.protocol is null and p2.priority = true) +--THis handles when a priority is placed on Room and Protocol -- +Left Join onprc_ehr.vet_assignment p3 on (p3.protocol.displayName = d.protocol and p3.room = d.room and p3.priority = true) +--THis handles when a priority is placed on Areaand Protocol - +Left Join onprc_ehr.vet_assignment p4 on (p4.protocol.displayName = d.protocol and p4.area = d.room.area and p4.priority = true) +--these deal with assignment based on housing only +Left join onprc_ehr.vet_assignment h1 on (h1.room = d.room and h1.protocol is null and h1.area is null and h1.priority = false) +Left join onprc_ehr.vet_assignment h2 on (h2.area = d.room.area and h2.room is null and h2.protocol is null and h2.priority = false) +where d.id not like '[a-z]%' \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/hematologyPivot.sql b/onprc_ehr/resources/queries/study/hematologyPivot.sql index 7768760a5..70a4459f5 100644 --- a/onprc_ehr/resources/queries/study/hematologyPivot.sql +++ b/onprc_ehr/resources/queries/study/hematologyPivot.sql @@ -37,7 +37,7 @@ FROM GROUP BY b.id, b.date, b.runId, b.testId, b.method,b.createdby PIVOT results BY testId IN -(select testid from ehr_lookups.hematology_tests t WHERE t.includeInPanel = true)) pvt +(select testid from ehr_lookups.hematology_tests t WHERE t.includeInPanel = true order by sort_order)) pvt LEFT OUTER JOIN diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql index 0de786a9d..e24e9410b 100644 --- a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior.sql @@ -4,9 +4,9 @@ select a.id,a.date,a.reviewdate, a.isactive, a.allproblemcategories, a.caseHistory, +a.isopen, b.observations from study.cases a, mostrecentobservationsforcase b where a.id = b.id and a.objectid = b.caseid and a.category = 'Behavior' -and a.isopen = true \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/All Behavior Cases.qview.xml b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/All Behavior Cases.qview.xml new file mode 100644 index 000000000..32b94fa86 --- /dev/null +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/All Behavior Cases.qview.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml index c7fc1db44..5fcf9794e 100644 --- a/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml +++ b/onprc_ehr/resources/queries/study/mostRecentObservationsBehavior/Open Behavior Case.qview.xml @@ -23,4 +23,7 @@
+ + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql b/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql new file mode 100644 index 000000000..24d4e6d6c --- /dev/null +++ b/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql @@ -0,0 +1,82 @@ +--Reviewed 2/7/2019 to update from vet_AssignmentDemographics_new +--Is the depenency for vet_assignmentSelect + +SELECT +Distinct + +d.Id, +d.gender, +d.species, +d.geographic_origin, +d.birth, +d.death, +h.room.area, +h.room, +d.calculated_status, +TimeStampAdd('SQL_TSI_YEAR', -1,Now()) as LastYear, +--n.assignedVet as DeceaseDAssignedVet, +c.vetNames as CaseVet, +c.category, + CASE + -- WHEN (n.status IS NOT null) THEN 'DECEASED NHP' + WHEN (c.id IS NOT NULL) THEN 'Active Case' + WHen r1.id is not null then 'Research Assigned' + WHen r2.id is not null then 'Resource Assigned' + + ELSE 'P51' + END as assignmentType, + +Case + when r1.protocol is not null then r1.use_Category + when r2.protocol is not null then r2.use_category + else ' ' + End As use_category, +--r1.use_Category, +--This needs to be a case statement that resturned the protocol whether Resource or research with research being the priority + +Case + when r1.protocol is not null then r1.protocol.displayName + when r2.protocol is not null then r2.protocol.displayName + else ' ' + End As protocol, + +--r1.protocol +FROM study.demographics d + +--Handles Deceased NHPs +/* +LEFT JOIN ( + Select + n.id, + vd.assignedVet, + 'Deceased' as status + from study.deaths n join study.vetAssignedDeceased vd on n.Id = vd.id + where n.date > TimeStampAdd('SQL_TSI_month', -3,Now())) + n on (n.Id =d.id) +*/ + +--Handles NHPS with active Cases + +LEFT JOIN ( + SELECT + c.Id, + c.category, + c.assignedvet.DisplayName as vetNames, + c.date + + FROM study.cases c + WHERE (c.category != 'Behavior' and c.enddateCoalesced >= curdate() ) + and c.allProblemCategories not like 'Routine%' + GROUP BY c.Id,c.category,c.date,c.assignedvet.DisplayName +) c ON (c.Id = d.Id) + +--Review for Assigned Animals +Left Join study.vet_AssignedResearch r1 on d.id = r1.id +Left Join study.vet_assignedResource r2 on d.id = r2.id and r2.id not in (Select r3.id from study.vet_AssignedResearch r3) +Left Join study.housing h on h.id = d.id and (h.enddateTimeCoalesced >= now()) + +--report only on animals that are alive or deceased in last year +where + (d.calculated_Status = 'Alive') + and d.id not Like '[A-Z]%' + --and (d.death is null or d.death > TimeStampAdd('SQL_TSI_MONTH', -2,Now()))) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignmentselect.sql b/onprc_ehr/resources/queries/study/vet_assignmentselect.sql new file mode 100644 index 000000000..90854e092 --- /dev/null +++ b/onprc_ehr/resources/queries/study/vet_assignmentselect.sql @@ -0,0 +1,54 @@ +SELECT +d.Id, +d.room.area as Area, +d.room, + +Case + when d.deceaseDAssignedVet is not null then 'Deceased NHP' + when d.caseVet is not null then 'Open Case' + when v1.userId.userId.DisplayName is not null then 'research Room' + when v2.userId.userId.DisplayName is not null then 'REsearch Area' + when v3.userId.userId.DisplayName is not null then 'Resource Room' + when v4.userId.userId.DisplayName is not null then 'Resource Area' + when v5.userId.userId.DisplayName is not null then 'Research Only' + when v6.userId.userId.DisplayName is not null then 'Resource Only' + when p1.userId.userId.DisplayName is not null then 'Room Priority' + when p2.userId.userId.DisplayName is not null then 'AreaPriority' + when h1.userId.userId.DisplayName is not null then 'Room Only' + when h2.userId.userId.DisplayName is not null then 'Area Only' + Else ' ' + End as AssignmentType, + +d.deceaseDAssignedVet as DeceasedVet, +d.CaseVet, +v1.userId.userId.DisplayName as ResearchRoom, +v2.userId.userId.DisplayName as REsearchArea, +v3.userId.userId.DisplayName as REsourceRoom, +v4.userId.userId.DisplayName as ResourceArea, +v5.userId.userId.DisplayName as ResearchOnly, +v6.userId.userId.DisplayName as ResourceOnly, +p1.userId.userId.DisplayName as RoomPriority, +p2.userId.userId.DisplayName as AreaPriority, +h1.userId.userId.DisplayName as RoomOnly, +h2.userId.userId.DisplayName as AreaOnly + + +FROM study.vet_assignmentDemographics d +--this handles REsearch Protocol Room +Left Join onprc_ehr.vet_assignment v1 on (v1.protocol = d.protocol and v1.room = d.room and d.assignmentType = 'Research Assigned') +--this handles Research Protocol Area +Left Join onprc_ehr.vet_assignment v2 on (v2.protocol = d.protocol and v2.area = d.room.area and d.assignmentType = 'Research Assigned') +--this handles Resource Protocol Room +Left Join onprc_ehr.vet_assignment v3 on (v3.protocol = d.protocol and v3.room = d.room and d.assignmentType = 'Resource Assigned') +--this handles Research Protocol Area +Left Join onprc_ehr.vet_assignment v4 on (v4.protocol = d.protocol and v4.area = d.room.area and d.assignmentType = 'Resource Assigned') +--this handled Research Assigned No Additional Sekections +Left Join onprc_ehr.vet_assignment v5 on (v5.protocol = d.protocol and d.assignmentType = 'Research Assigned' and (v5.area is null and v5.room is null)) +--this handles resource Protocol Only +Left Join onprc_ehr.vet_assignment v6 on (v6.protocol = d.protocol and d.assignmentType = 'Resource Assigned' and (v6.area is null and v5.room is null)) +--this handles when the room is a priorty +Left join onprc_ehr.vet_assignment p1 on (p1.room = d.room and p1.priority = true) +--this handles when the room is a priorty +Left join onprc_ehr.vet_assignment p2 on (p2.area = d.room.area and p2.priority = true) +Left join onprc_ehr.vet_assignment h1 on (h1.room = d.room and h1.priority = false) +Left join onprc_ehr.vet_assignment h2 on (h2.area = d.room.area and h2.priority = false) diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index 006d57127..be80816d9 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -486,13 +486,6 @@ exports.init = function(EHR){ } }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_INSERT, 'study', 'blood', function(helper, scriptErrors, row){ - if (!helper.isETL() && row.project && row.chargetype){ - if (row.chargetype == 'No Charge' && !helper.getJavaHelper().isDefaultProject(row.project)) - EHR.Server.Utils.addError(scriptErrors, 'chargetype', 'You have chosen \'No Charge\' with a project that does not support this. You may need to choose \'Research\' instead (which is not billed)', 'INFO'); - } - }); - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'housing', function(helper, scriptErrors, row, oldRow){ if (row.cage){ row.cage = row.cage.toUpperCase(); @@ -775,6 +768,94 @@ exports.init = function(EHR){ EHR.Server.TriggerManager.registerHandler(EHR.Server.TriggerManager.Events.INIT, function (event, helper) { + + /* Override the default EHR validation for Blood draw validation. By LKolli, 2/01/2019 */ + + //unregister the default EHR validation code + EHR.Server.TriggerManager.unregisterAllHandlersForQueryNameAndEvent('study', 'blood', EHR.Server.TriggerManager.Events.BEFORE_UPSERT); + //register the new validation code + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'blood', function (helper, scriptErrors, row, oldRow) { + if (!helper.isETL() && row.date && !row.daterequested){ + if (!oldRow || !oldRow.daterequested){ + row.daterequested = row.date; + } + } + + if (row.quantity === 0){ + EHR.Server.Utils.addError(scriptErrors, 'quantity', 'This field is required', 'WARN'); + } + + if (!helper.isETL()){ + if (row.date && !row.requestdate) + row.requestdate = row.date; + + if (!row.quantity && row.num_tubes && row.tube_vol){ + row.quantity = row.num_tubes * row.tube_vol; + } + + if (row.additionalServices) { + if (row.tube_type || row.tube_vol){ + var tubeType = row.tube_type || null; + var quantity = row.quantity || 0; + var msgs = helper.getJavaHelper().validateBloodAdditionalServices(row.additionalServices, tubeType, quantity); + if (msgs && msgs.length){ + LABKEY.ExtAdapter.each(msgs, function(msg){ + EHR.Server.Utils.addError(scriptErrors, 'additionalServices', msg, 'INFO'); + }, this); + } + } + } + + if (row.quantity && row.tube_vol){ + if (row.quantity != (row.num_tubes * row.tube_vol)){ + EHR.Server.Utils.addError(scriptErrors, 'quantity', 'Quantity does not match tube vol / # tubes', 'INFO'); + EHR.Server.Utils.addError(scriptErrors, 'num_tubes', 'Quantity does not match tube vol / # tubes', 'INFO'); + } + } + + EHR.Server.Validation.checkRestraint(row, scriptErrors); + + if (row.Id && row.date && row.quantity){ + // volume is handled differently for requests vs actual draws + var errorQC; + if (EHR.Server.Security.getQCStateByLabel(row.QCStateLabel)['isRequest'] && !row.taskid) + errorQC = 'ERROR'; + else + errorQC = 'INFO'; + + var map = helper.getProperty('bloodInTransaction'); + var draws = []; + if (map && map[row.Id]){ + draws = map[row.Id]; + } + + var weightMap = helper.getProperty('weightInTransaction'); + var weights = []; + if (weightMap && weightMap[row.Id]){ + weights = weightMap[row.Id]; + } + + if (row.objectid) { + + if ((row.QCStateLabel != 'Request: Cancelled') || (row.QCStateLabel != 'Request: Denied')) + { + //Calling the new ONPRC blood draw validation code, LKolli, 2/1/2019 + var msg = triggerHelper.verifyBloodVolume_New(row.id, row.date, draws, weights, row.objectid || null, row.quantity); + if (msg != null) { + //TODO: change all future bloods draws to review required, if submitted for medical purpose. + EHR.Server.Utils.addError(scriptErrors, 'num_tubes', msg, errorQC); + EHR.Server.Utils.addError(scriptErrors, 'quantity', msg, errorQC); + } + } + } + else { + console.warn('objectid not provided for blood draw, cannot calculate allowable blood volume. this probably indicates an error with the form submitting these data') + } + } + } + }); + + // Override the default EHR validation for project creation EHR.Server.TriggerManager.unregisterAllHandlersForQueryNameAndEvent('ehr', 'project', EHR.Server.TriggerManager.Events.BEFORE_UPSERT); @@ -790,4 +871,6 @@ exports.init = function(EHR){ } }); }); + + }; \ No newline at end of file diff --git a/onprc_ehr/resources/views/begin.html b/onprc_ehr/resources/views/begin.html index b1f3e37c6..a560fedee 100644 --- a/onprc_ehr/resources/views/begin.html +++ b/onprc_ehr/resources/views/begin.html @@ -109,8 +109,8 @@ items: [ {name: 'Compare Lists of Animals', url: '<%=contextPath%>/ehr' + ctx['EHRStudyContainer'] + '/utilities.view?'}, {name: 'Bulk History Export', url: '<%=contextPath%>/onprc_ehr' + ctx['EHRStudyContainer'] + '/historyExport.view?'}, - //Modified: 8-30-2016 R.Blasa - {name: 'Exposure Report', url: ctx['SSRSServerURL'] +'%2fAnnual+Reports%2fExposure+Report%2fDemographicsReportMain&rs:Command=Render'}, + //Modified: 1-17-2019 R.Blasa + {name: 'Exposure Report', url: ctx['SSRSServerURL'] +'%2fPrime+Reports%2fExposure+Reports%2fDemographicsReportMain&rs:Command=Render'}, {name: 'Drug Formulary', url: '<%=contextPath%>/query' + ctx['EHRStudyContainer'] + '/executeQuery.view?schemaName=ehr_lookups&query.queryName=drug_defaults'}, {name: 'Procedure List', url: '<%=contextPath%>/query' + ctx['EHRStudyContainer'] + '/executeQuery.view?schemaName=ehr_lookups&query.queryName=procedures&query.viewName=Active Procedures'}, {name: 'Search Center SNOMED Codes', url: '<%=contextPath%>/query' + ctx['EHRStudyContainer'] + '/executeQuery.view?schemaName=ehr_lookups&query.queryName=snomed'} diff --git a/onprc_ehr/resources/views/citesReport.html b/onprc_ehr/resources/views/citesReport.html index 1bd4ac80b..148fc7829 100644 --- a/onprc_ehr/resources/views/citesReport.html +++ b/onprc_ehr/resources/views/citesReport.html @@ -39,10 +39,10 @@ Ext4.Msg.alert('Error', 'Must enter at least one animal Id'); return; } - + //Modified: 1-17-2019 R.Blasa var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'CITESReport'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/CITESReport'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString({ SessionID: LABKEY.Utils.getSessionID(), diff --git a/onprc_ehr/resources/views/historyExport.html b/onprc_ehr/resources/views/historyExport.html index 29e3354d2..6ed80843f 100644 --- a/onprc_ehr/resources/views/historyExport.html +++ b/onprc_ehr/resources/views/historyExport.html @@ -73,11 +73,11 @@ Ext4.Msg.alert('Error', 'Must enter at least one animal Id'); return; } - + //Modified: 1-17-2019 R.Blasa if (!hideHistory){ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'SalesMedicalHistoryReport'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/SalesMedicalHistoryReport'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString({ SessionID: LABKEY.Utils.getSessionID(), diff --git a/onprc_ehr/resources/views/printableReports.html b/onprc_ehr/resources/views/printableReports.html index 89f4d6f7d..ceac1a872 100644 --- a/onprc_ehr/resources/views/printableReports.html +++ b/onprc_ehr/resources/views/printableReports.html @@ -155,7 +155,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'ActiveClinicalCasesVet'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveClinicalCasesVet'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); @@ -224,7 +224,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'ActiveClinicalCases'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveClinicalCases'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); @@ -316,7 +316,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'ActiveTreatments'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveTreatments'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; @@ -407,7 +407,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'ActiveTreatments'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveTreatments'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; @@ -474,7 +474,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'ActiveSurgicalCases'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveSurgicalCases'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; @@ -565,7 +565,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'ActiveTreatments'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveTreatments'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; @@ -629,7 +629,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'WeightSheets'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/WeightSheets'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; @@ -699,7 +699,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'WeightSheetsGroup'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/WeightSheetsGroup'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; @@ -784,7 +784,7 @@ var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'WeightSheetsID'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/WeightSheetsID'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); return url; diff --git a/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js b/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js index e7f66d517..069f3c1da 100644 --- a/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js +++ b/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js @@ -68,6 +68,11 @@ EHR.DemographicsRecord = function(data){ return data['fosterchild']; }, + //Added 12-20-2018 R.Blasa + getLastKnownlocation: function(){ + return data['lastlocation']; + }, + getCurrentLocation: function(){ if (data['activeHousing'] && data['activeHousing'].length){ var ret = data['activeHousing'][0].room; diff --git a/onprc_ehr/resources/web/onprc_ehr/buttons/pathologyButtons.js b/onprc_ehr/resources/web/onprc_ehr/buttons/pathologyButtons.js index 3bf9a7b09..7215a7d18 100644 --- a/onprc_ehr/resources/web/onprc_ehr/buttons/pathologyButtons.js +++ b/onprc_ehr/resources/web/onprc_ehr/buttons/pathologyButtons.js @@ -191,6 +191,21 @@ EHR.DataEntryUtils.registerDataEntryFormButton('ENTERDEATH_FOR_TISSUES', { } }); +EHR.DataEntryUtils.registerGridButton('PATH_SAVE_DRAFT', function(config) { + return Ext4.Object.merge({ + text: 'Save Draft', + name: 'saveDraft', + requiredQC: 'In Progress', + errorThreshold: 'WARN', + disabled: false, + itemId: 'saveDraftBtn', + handler: function(btn){ + var panel = btn.up('ehr-dataentrypanel'); + panel.onSubmit(btn) + }, + disableOn: 'ERROR' + }, config); +}); EHR.DataEntryUtils.registerGridButton('RESET_SORT_ORDER', function(config){ return Ext4.Object.merge({ text: 'Reset Sort Order', diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js index 96ca24c50..b6956c480 100644 --- a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js @@ -10,6 +10,16 @@ */ EHR.model.DataModelManager.registerMetadata('Default', { byQuery: { + + //Kolli1 3/19: Added this code to display the description field in the protocol details data entry screen. The Description field is hidden in the core. (Defaults.js) + // To overwrite the core code, this snippet is added on the onprc side + 'ehr.protocol': { + description: { + hidden: false, + label: "Notes" + } + }, + 'study.blood' : { tube_vol: { hidden: true @@ -32,6 +42,17 @@ EHR.model.DataModelManager.registerMetadata('Default', { }, + // //Added: 1-23-2019 R.Blasa allow drug sedation alert notification + // 'study.drug': { + // description: { + // hidden: false, + // width: 200 + // }, + // reason: { + // hidden: true, + // } + // }, + //Added: 12-27-2017 R.Blasa 'study.Arrival': { date: { diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css b/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css index cbb102d3d..d7115e948 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Gross_Finding.css @@ -1,4 +1,7 @@ .x4-form-item, .x4-form-field { - font: normal 14px "Arial", Arial, Helvetica, sans-serif; } \ No newline at end of file + font: normal 14px "Arial", Arial, Helvetica, sans-serif; } + +.x4-grid-editor +.x4-form-text{font: normal 14px/13px 'Roboto',Arial,Helvetica,sans serif;padding:1px 5px 2px 5px;height:20px;} \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsPanel.js new file mode 100644 index 000000000..7d350807e --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/panel/AnimalDetailsPanel.js @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2013-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + * + * @param subjectId + */ +Ext4.define('ONPC_EHR.panel.AnimalDetailsPanel', { + extend: 'onprc_ehr.panel.SnapshotPanel', + alias: 'widget.onprc_ehr-animaldetailspanels', + + border: true, + showExtendedInformation: false, + showActionsButton: false, + doSuspendLayouts: false, + showDisableButton: true, + + initComponent: function(){ + Ext4.apply(this, { + border: true, + bodyStyle: 'padding: 5px;', + minHeight: 285, + defaults: { + border: false + } + }); + + this.callParent(arguments); + + if (this.dataEntryPanel){ + this.mon(this.dataEntryPanel, 'animalchange', this.onAnimalChange, this, {buffer: 500}); + } + + this.mon(EHR.DemographicsCache, 'cachechange', this.demographicsListener, this); + }, + + demographicsListener: function(animalId){ + if (this.isDestroyed){ + console.log('is destroyed'); + return; + } + + if (animalId == this.subjectId){ + this.loadAnimal(animalId, true); + } + }, + + onAnimalChange: function(animalId){ + //the intent of this is to avoid querying partial strings as the user types + if (animalId && animalId.length < 4){ + animalId = null; + } + + this.loadAnimal(animalId); + }, + + loadAnimal: function(animalId, forceReload){ + if (!forceReload && animalId == this.subjectId){ + return; + } + + this.subjectId = animalId; + + if (animalId) + EHR.DemographicsCache.getDemographics([this.subjectId], this.onLoad, this, (forceReload ? 0 : -1)); + else + this.getForm().reset(); + }, + + onLoad: function(ids, resultMap){ + if (ids && ids.length && ids[0] != this.subjectId){ + return; + } + + this.callParent(arguments); + }, + + getItems: function(){ + return [{ + itemId: 'columnSection', + layout: 'column', + defaults: { + border: false, + bodyStyle: 'padding-right: 20px;' + }, + items: [{ + xtype: 'container', + width: 380, + defaults: { + xtype: 'displayfield', + labelWidth: this.defaultLabelWidth + }, + items: [{ + fieldLabel: 'Id', + name: 'animalId' + },{ + fieldLabel: 'Location', + name: 'location' + },{ + fieldLabel: 'Last Recorded Location', //Added: 12-19-2018 R.Blasa + name: 'lastlocation' + },{ + fieldLabel: 'Gender', + name: 'gender' + },{ + fieldLabel: 'Species', + name: 'species' + },{ + fieldLabel: 'Age', + name: 'age' + },{ + xtype: 'displayfield', + fieldLabel: 'Source', + name: 'source' + },{ + fieldLabel: 'Projects / Groups', + name: 'assignmentsAndGroups' + }] + },{ + xtype: 'container', + width: 350, + defaults: { + xtype: 'displayfield' + }, + items: [{ + fieldLabel: 'Status', + name: 'calculated_status' + },{ + fieldLabel: 'Flags', + name: 'flags' + },{ + fieldLabel: 'Weight', + name: 'weights' + },{ + xtype: 'ldk-linkbutton', + style: 'margin-top: 10px;', + scope: this, + text: '[Show Full Hx]', + handler: function(){ + if (this.subjectId){ + EHR.window.ClinicalHistoryWindow.showClinicalHistory(null, this.subjectId, null); + } + else { + console.log('no id'); + } + } + },{ + xtype: 'ldk-linkbutton', + style: 'margin-top: 5px;', + scope: this, + text: '[Show Recent SOAPs]', + handler: function(){ + if (this.subjectId){ + EHR.window.RecentRemarksWindow.showRecentRemarks(this.subjectId); + } + else { + console.log('no id'); + } + } + },{ + xtype: 'ldk-linkbutton', + style: 'margin-top: 5px;', + scope: this, + text: '[Manage Treatments]', + hidden: EHR.Security.hasClinicalEntryPermission() && !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'update', [{schemaName: 'study', queryName: 'Treatment Orders'}]), + handler: function(){ + if (this.subjectId){ + Ext4.create('EHR.window.ManageTreatmentsWindow', {animalId: this.subjectId}).show(); + } + else { + console.log('no id'); + } + } + },{ + xtype: 'ldk-linkbutton', + style: 'margin-top: 5px;margin-bottom:10px;', + scope: this, + text: '[Manage Cases]', + hidden: EHR.Security.hasClinicalEntryPermission() && !EHR.Security.hasPermission(EHR.QCStates.COMPLETED, 'update', [{schemaName: 'study', queryName: 'Cases'}]), + handler: function(){ + if (this.subjectId){ + Ext4.create('EHR.window.ManageCasesWindow', {animalId: this.subjectId}).show(); + } + else { + console.log('no id'); + } + } + }] + }] + },{ + layout: 'hbox', + style: 'padding-top: 10px;', + items: [{ + xtype: 'button', + border: true, + text: 'Reload', + scope: this, + handler: function(btn){ + this.loadAnimal(this.subjectId, true); + } + },{ + xtype: 'button', + hidden: !this.showDisableButton, + border: true, + text: 'Disable', + style: 'margin-left: 10px;', + scope: this, + handler: function(btn){ + this.disableAnimalLoad = btn.getText() == 'Disable'; + + btn.setText(this.disableAnimalLoad ? 'Enable' : 'Disable'); + this.down('#columnSection').setDisabled(this.disableAnimalLoad); + } + }] + }]; + }, + + appendWeightResults: function(toSet, results){ + var text; + if (results && results.length){ + var row = results[0]; + var date = LDK.ConvertUtils.parseDate(row.date); + var interval = ''; + if (date){ + //round to day for purpose of this comparison + var d1 = Ext4.Date.clearTime(new Date(), true); + var d2 = Ext4.Date.clearTime(date, true); + interval = Ext4.Date.getElapsed(d1, d2); + interval = interval / (1000 * 60 * 60 * 24); + interval = Math.floor(interval); + interval = interval + ' days ago'; + } + + text = row.weight + ' kg, ' + date.format(LABKEY.extDefaultDateFormat) + (!Ext4.isEmpty(interval) ? ' (' + interval + ')' : ''); + } + + toSet['weights'] = text; + }, + + appendAssignmentsAndGroups: function(toSet, record){ + toSet['assignmentsAndGroups'] = null; + + if (this.redacted) + return; + + var values = []; + if (record.getActiveAssignments() && record.getActiveAssignments().length){ + Ext4.each(record.getActiveAssignments(), function(row){ + var val = row['project/investigatorId/lastName'] || ''; + val += ' [' + row['project/displayName'] + ']'; + + if (val) + values.push(val); + }, this); + } + + if (record.getActiveAnimalGroups() && record.getActiveAnimalGroups().length){ + Ext4.each(record.getActiveAnimalGroups(), function(row){ + values.push(row['groupId/name']); + }, this); + } + + toSet['assignmentsAndGroups'] = values.length ? values.join('
') : null; + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js index 60959f032..53721355f 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js @@ -234,6 +234,9 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { this.appendFosterChildtResults(toSet, results.getFosterChild()); + //Added: 12-20-2018 R.Blasa + this.appendLastKnownLocationResults(toSet, results.getLastKnownlocation()); + if (this.showExtendedInformation){ this.appendBirthResults(toSet, results.getBirthInfo(), results.getBirth()); @@ -357,6 +360,26 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { }, + //Added: 12-20-2018 R.Blasa Last Known Locatoni + appendLastKnownLocationResults: function(toSet, results){ + var values = []; + if (results) + { + Ext4.each(results, function(row){ + var lastlocation = row.location; + + values.push(lastlocation); + + }, this); + + } + + toSet['lastlocation'] = values.length ? values.join('
') : 'None'; + + }, + + + appendWeightResults: function(toSet, results){ @@ -493,6 +516,48 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { } }, + //Modified: 12-20-2018 R.Blasa + appendDemographicsResults: function(toSet, row, id){ + if (!row){ + console.log('Id not found'); + return; + } + + var animalId = row.getId() || id; + if (!Ext4.isEmpty(animalId)){ + toSet['animalId'] = id; + } + + var status = row.getCalculatedStatus() || 'Unknown'; + toSet['calculated_status'] = '' + status + ''; + + toSet['species'] = row.getSpecies(); + toSet['geographic_origin'] = row.getGeographicOrigin(); + toSet['gender'] = row.getGender(); + toSet['age'] = row.getAgeInYearsAndDays(); + + var location; + if (row.getActiveHousing() && row.getActiveHousing().length){ + var housingRow = row.getActiveHousing(); + location = ''; + if (!Ext4.isEmpty(row.getCurrentRoom())) + location = row.getCurrentRoom(); + if (!Ext4.isEmpty(row.getCurrentCage())) + location += ' / ' + row.getCurrentCage(); + + if (location){ + if (this.showLocationDuration && housingRow.date){ + var date = LDK.ConvertUtils.parseDate(housingRow.date); + if (date) + location += ' (' + date.format(LABKEY.extDefaultDateFormat) + ')'; + } + } + } + + toSet['location'] = location || 'No active housing'; + + }, + //Modified: 5-10-2018 R.Blasa appendFlags: function(toSet, results){ var values = []; diff --git a/onprc_ehr/resources/web/onprc_ehr/window/CreateTaskFromRecordsWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/CreateTaskFromRecordsWindow.js new file mode 100644 index 000000000..16d87b08a --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/window/CreateTaskFromRecordsWindow.js @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @cfg formType + * @cfg taskLabel + */ + +//Created: 1-18-2019 R.Blasa + +Ext4.define('ONPRC_EHR.window.CreateTaskFromRecordsWindow', { + extend: 'Ext.window.Window', + + selectField: 'lsid', + title: 'Create Task', + + statics: { + /** + * This add a button that allows the user to create a task from a list of IDs, that contains one record per ID. It was originally + * created to allow users to create a weight task based on a list of IDs (like animals needed weights). + */ + createTaskFromRecordHandler: function(dataRegionName, formType, taskLabel){ + var dataRegion = LABKEY.DataRegions[dataRegionName]; + var checked = dataRegion.getChecked(); + if (!checked || !checked.length){ + Ext4.Msg.alert('Error', 'No records selected'); + return; + } + + Ext4.create('ONPRC_EHR.window.CreateTaskFromRecordsWindow', { + dataRegionName: dataRegionName, + title: 'Schedule ' + taskLabel + " For Selected Rows", + formType: formType, + taskLabel: taskLabel + }).show(); + } + }, + + initComponent: function(){ + LDK.Assert.assertNotEmpty('Missing formtype in CreateTaskFromRecordsWindow', this.formType); + + Ext4.apply(this, { + modal: true, + closeAction: 'destroy', + width: 400, + items: [{ + xtype: 'form', + itemId: 'theForm', + bodyStyle: 'padding: 5px;', + defaults: { + border: false, + width: 360 + }, + items: [{ + html: 'Total Selected: ' + '

', + border: false + },{ + xtype: 'radiogroup', + itemId: 'type', + defaults: { + name: 'type', + xtype: 'radio' + }, + items: [{ + boxLabel: 'Create New Task', + inputValue: 'createNew', + checked: true + },{ + boxLabel: 'Add To Existing Task', + inputValue: 'addToExisting' + }], + listeners: { + scope: this, + change: function(field, val){ + var panel = this.down('#taskItems'); + panel.removeAll(); + if (val.type == 'createNew'){ + panel.add(this.getTaskItems()); + } + else { + panel.add(this.getAddToExistingItems()); + } + } + } + },{ + xtype: 'form', + itemId: 'taskItems', + items: this.getTaskItems(), + defaults: { + border: false, + width: 360 + } + }] + }], + buttons: this.getButtonCfg() + }); + + this.callParent(); + + this.on('render', function(){ + this.setLoading(true); + this.loadData(); + }, this, {single: true, delay: 100}); + }, + + getAddToExistingItems: function(){ + return [{ + xtype: 'labkey-combo', + itemId: 'taskField', + fieldLabel: 'Choose Task', + labelAlign: 'top', + forceSelection: true, + displayField: 'title', + valueField: 'taskid', + listConfig: { + innerTpl: ['{rowid}: {title}'] + }, + store: { + type: 'labkey-store', + schemaName: 'ehr', + queryName: 'tasks', + filterArray: [ + LABKEY.Filter.create('qcstate/publicData', false, LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('formtype', this.formType, LABKEY.Filter.Types.EQUAL) + ], + columns: 'taskid,assignedto/DisplayName,title,rowid', + sort: '-rowid' + } + }] + }, + + getTaskItems: function(){ + return [{ + xtype: 'textfield', + fieldLabel: 'Task Title', + value: this.taskLabel, + itemId: 'titleField' + },{ + xtype: 'xdatetime', + fieldLabel: 'Date', + value: new Date(), + itemId: 'date' + },{ + xtype: 'combo', + fieldLabel: 'Assigned To', + forceSelection: true, + value: LABKEY.Security.currentUser.id, + queryMode: 'local', + store: { + type: 'labkey-store', + schemaName: 'core', + queryName: 'PrincipalsWithoutAdmin', + columns: 'UserId,DisplayName', + sort: 'Type,DisplayName', + autoLoad: true + }, + displayField: 'DisplayName', + valueField: 'UserId', + itemId: 'assignedTo' + },{ + xtype: 'checkbox', + fieldLabel: 'View Task After Created?', + itemId: 'viewAfterCreate', + checked: true + }] + }, + + getButtonCfg: function(){ + return [{ + text: 'Submit', + itemId: 'submitBtn', + scope: this, + disabled: true, + handler: this.onSubmit + },{ + text: 'Cancel', + handler: function(btn){ + btn.up('window').close(); + } + }]; + }, + + loadData: function(){ + var dataRegion = LABKEY.DataRegions[this.dataRegionName]; + LDK.Assert.assertNotEmpty('Unknown dataregion: ' + this.dataRegionName, dataRegion); + + this.checkedRows = dataRegion.getChecked(); + + LABKEY.Query.selectRows({ + method: 'POST', + requiredVersion: 9.1, + schemaName: dataRegion.schemaName, + queryName: dataRegion.queryName, + sort: 'Id,date', + columns: 'lsid,Id,date,requestid,taskid,qcstate,qcstate/label,qcstate/metadata/isRequest', + filterArray: [LABKEY.Filter.create('lsid', this.checkedRows.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)], + scope: this, + success: this.onDataLoad, + failure: LDK.Utils.getErrorCallback() + }); + }, + + onDataLoad: function(data){ + if (!data || !data.rows){ + Ext4.Msg.hide(); + Ext4.Msg.alert('Error', 'No records found'); + return; + } + + this.records = []; + var errors = []; + + //first order these rows based on the source dataregion + var sortedRows = data.rows; + var checked = this.checkedRows; + var pk = this.pkCol; + sortedRows = sortedRows.sort(function(a, b){ + var rowA = new LDK.SelectRowsRow(a); + var rowB = new LDK.SelectRowsRow(b); + + var idxA = checked.indexOf(rowA.getValue('lsid')); + var idxB = checked.indexOf(rowB.getValue('lsid')); + LDK.Assert.assertTrue('Unable to find row matching: ' + rowA.getValue('lsid'), idxA > -1); + LDK.Assert.assertTrue('Unable to find row matching: ' + rowB.getValue('lsid'), idxB > -1); + + return idxA > idxB ? 1 : idxA < idxB ? -1 : 0; + }); + + Ext4.Array.forEach(sortedRows, function(json){ + var r = new LDK.SelectRowsRow(json); + if (r.getValue('taskid')){ + errors.push('One or more records is already part of a task and will be skipped.'); + } + else if (!r.getValue('qcstate/metadata/isRequest')){ + errors.push('Only requests can be added to tasks. One or more records was skipped.'); + } + else { + this.records.push(r); + } + }, this); + + if (errors.length){ + errors = Ext4.Array.unique(errors); + Ext4.Msg.alert('Error', errors.join('
')); + } + + var form = this.down('#theForm'); + form.remove(0); + form.insert(0, { + html: 'Total Selected: ' + this.records.length + '

', + border: false + }); + + this.down('#submitBtn').setDisabled(false); + this.setLoading(false); + }, + + onSubmit: function(){ + var records = this.getRecords(); + if (!records || !records.length) + return; + + var type = this.down('#type').getValue().type; + if (type == 'createNew'){ + this.doSaveNew(records); + } + else { + this.doAddToExisting(records); + } + }, + + doAddToExisting: function(records){ + var taskId = this.down('#taskField').getValue(); + if (!taskId){ + Ext4.Msg.alert('Error', 'Must choose a task'); + return; + } + + Ext4.Msg.wait('Saving...'); + + var toSave = []; + Ext4.Array.forEach(records, function(r, idx){ + toSave.push(Ext4.apply({ + taskid: taskId, + QCState: 25, //QCState: Scheduled Modified: 1-11-2019 R.Blasa Set after adding to an existing task id + formSort: idx + }, r)); + }, this); + + var dataRegion = LABKEY.DataRegions[this.dataRegionName]; + LABKEY.Query.updateRows({ + method: 'POST', + schemaName: dataRegion.schemaName, + queryName: dataRegion.queryName, + rows: toSave, + scope: this, + failure: LDK.Utils.getErrorCallback(), + success: this.onComplete + }); + }, + + doSaveNew: function(records){ + var date = this.down('#date').getValue(); + if(!date){ + Ext4.Msg.alert('Error', 'Must enter a date'); + } + + var assignedTo = this.down('#assignedTo').getValue(); + if(!assignedTo){ + Ext4.Msg.alert('Error', 'Must assign to someone'); + } + + var title = this.down('#titleField').getValue(); + if(!title){ + Ext4.Msg.alert('Error', 'Must enter a title'); + } + + Ext4.Msg.wait('Saving...'); + + var dataRegion = LABKEY.DataRegions[this.dataRegionName]; + var existingRecords = {}; + existingRecords[dataRegion.queryName] = []; + + Ext4.Array.forEach(records, function(r){ + LDK.Assert.assertNotEmpty('Record does not have an LSID', r.lsid); + existingRecords[dataRegion.queryName].push({lsid: r.lsid, formSort: r.formSort}); + }, this); + + EHR.Utils.createTask({ + initialQCState: 'Scheduled', + existingRecords: existingRecords, + taskRecord: {duedate: date, assignedTo: assignedTo, category: 'task', title: title, formType: this.formType}, + scope: this, + success: function(response, options, config){ + Ext4.Msg.hide(); + + var viewAfterCreate = this.down('#viewAfterCreate').getValue(); + this.close(); + + if (viewAfterCreate){ + window.location = LABKEY.ActionURL.buildURL('ehr', 'dataEntryForm', null, {taskid: config.taskId, formType: this.formType}); + } + else { + LABKEY.DataRegions[this.dataRegionName].refresh(); + } + }, + failure: LDK.Utils.getErrorCallback() + }); + }, + + getRecords: function(){ + var toSave = []; + Ext4.each(this.records, function(r, idx){ + toSave.push({ + lsid: r.getValue('lsid'), + formSort: idx + }); + }, this); + + if (!toSave.length){ + Ext4.Msg.alert('Nothing To Save', 'There are no records to save'); + return null; + } + + return toSave; + }, + + onComplete: function(){ + Ext4.Msg.hide(); + var dataRegion = LABKEY.DataRegions[this.dataRegionName]; + dataRegion.selectNone(); + dataRegion.refresh(); + this.close(); + } +}); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 3d1049709..c01cd1e79 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -60,6 +60,7 @@ import org.labkey.onprc_ehr.buttons.ProtocolEditButton; import org.labkey.onprc_ehr.buttons.VetReviewButton; import org.labkey.onprc_ehr.buttons.VetReviewRecordButton; +import org.labkey.onprc_ehr.buttons.CreateTaskFromRecordButtons; import org.labkey.onprc_ehr.dataentry.*; import org.labkey.onprc_ehr.demographics.ActiveAnimalGroupsDemographicsProvider; import org.labkey.onprc_ehr.demographics.ActiveCasesDemographicsProvider; @@ -72,6 +73,7 @@ import org.labkey.onprc_ehr.demographics.PregnancyConfirmDemographicsProvider; import org.labkey.onprc_ehr.demographics.SourceDemographicsProvider; import org.labkey.onprc_ehr.demographics.TBDemographicsProvider; +import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsEndDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalRecordFlagDataSource; @@ -288,16 +290,17 @@ private void registerEHRResources() //Added 5-16-2018 R.Blasa EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Date of Last Physical Exam by ID(s)", this, DetailsURL.fromString("/onprc_ehr/PE_ExamHistoryReportbyID.view"), "Routine Clinical Tasks"); - //Added 5-11-2015 New report for Lois Colgin + //Modified: 1-17-2019 R.Blasa try { - EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Laboratory Test Summary", this, new URLHelper("http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fPrimeLaboratory+Report&rs:Command=Render") + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Pathology Laboratory Summary Report", this, new URLHelper("http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render") { // SSRS is picky about the URI-encoding of the query parameters @Override public String toString() { - return "http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fPrimeLaboratory+Report&rs:Command=Render"; + return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render"; + } }, "Clinical Pathology"); } @@ -306,16 +309,17 @@ public String toString() throw new UnexpectedException(e); } - //Added 6-21-2017 R.Blasa + //Modified 1-7-2019 R.Blasa try { - EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Basic Exposure Report", this, new URLHelper("http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fExposure+Report%2fBasicExposureMain&rs:Command=Render") + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Basic Exposure Report", this, new URLHelper("http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fBasicExposureMain&rs:Command=Render") { // SSRS is picky about the URI-encoding of the query parameters @Override + //Modified: 1-17-2019 R.Blasa public String toString() { - return "http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fExposure+Report%2fBasicExposureMain&rs:Command=Render"; + return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fBasicExposureMain&rs:Command=Render"; } }, "Exposure Report"); } @@ -476,6 +480,9 @@ public String toString() //Created: 4-7-2015-10-2017 R.Blasa EHRService.get().registerDemographicsProvider(new ActiveTreatmentsXDemographicsProvider(this)); + //Created: 12-18-2018 R.Blasa + EHRService.get().registerDemographicsProvider(new LastHousingDemographicsProvider(this)); + //buttons EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "my_tasks"); EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "tasks"); @@ -510,8 +517,8 @@ public String toString() EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); - //Added: 7-29-2017 R.Blasa - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); + //Added: 1-18-2019 R.Blasa + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this), "study", "blood"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java new file mode 100644 index 000000000..14bda6595 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.buttons; + +import org.labkey.api.data.TableInfo; +import org.labkey.api.ehr.security.EHRScheduledInsertPermission; +import org.labkey.api.ldk.table.SimpleButtonConfigFactory; +import org.labkey.api.module.Module; +import org.labkey.api.security.permissions.Permission; +import org.labkey.api.study.DatasetTable; +import org.labkey.api.view.template.ClientDependency; + +import java.util.Set; + +//Createdd: 1-18-2019 R.Blasa + +public class CreateTaskFromRecordButtons extends SimpleButtonConfigFactory +{ + public CreateTaskFromRecordButtons(Module owner, String btnLabel, String taskLabel, String formType) + { + super(owner, btnLabel, "ONPRC_EHR.window.CreateTaskFromRecordsWindow.createTaskFromRecordHandler(dataRegionName, '" + formType + "', '" + taskLabel + "')"); + setClientDependencies(ClientDependency.fromPath("onprc_ehr/window/CreateTaskFromRecordsWindow.js")); //Modified: 1-19-2019 R.Blasa + + } + + public boolean isAvailable(TableInfo ti) + { + if (!super.isAvailable(ti)) + return false; + + if (ti instanceof DatasetTable) + { + Set> perms = ((DatasetTable) ti).getDataset().getPermissions(ti.getUserSchema().getUser()); + return perms.contains(EHRScheduledInsertPermission.class); + } + + return ti.hasPermission(ti.getUserSchema().getUser(), EHRScheduledInsertPermission.class); + } +} + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java new file mode 100644 index 000000000..f55ca91ca --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.dataentry. NonStoreFormSection; +import org.labkey.api.view.template.ClientDependency; + +//Created:12-20-2018 R.Blasa + +public class AnimalDetailssFormSection extends NonStoreFormSection +{ + public AnimalDetailssFormSection() + { + super("AnimalDetails", "Animal Details", "onprc_ehr-animaldetailspanels"); + addClientDependency(ClientDependency.fromPath("onprc_ehr/panel/AnimalDetailsPanel.js")); + + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/LabworkRequestFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/LabworkRequestFormType.java index 5ad0da829..3d1715692 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/LabworkRequestFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/LabworkRequestFormType.java @@ -40,7 +40,10 @@ public LabworkRequestFormType(DataEntryFormContext ctx, Module owner) { super(ctx, owner, NAME, LABEL, "Requests", Arrays.asList( new RequestFormSection(), - new LabworkRequestInstructionsFormSection(), + + //Modified: 1-14-2019 R. Blasa No longer need Merge web link +// new LabworkRequestInstructionsFormSection(), + new AnimalDetailsFormSection(), new ClinpathRunsFormSection(true) )); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java index 5579a065e..4d0344f3e 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java @@ -51,7 +51,8 @@ public NecropsyFormType(DataEntryFormContext ctx, Module owner) new NonStoreFormSection("Instructions", "Instructions", "ehr-necropsyinstructionspanel", Arrays.asList(ClientDependency.supplierFromPath("ehr/panel/NecropsyInstructionsPanel.js"))), new TaskFormSection(), new ClinicalEncountersFormPanelSection("Necropsy"), - new AnimalDetailsFormSection(), + //Modified: 12-20-2018 R.Blasa + new AnimalDetailssFormSection(), new GrossFindingsFormPanelSection(), new PathologyFormSection("ehr", "encounter_participants", "Staff"), new PathologyNotesFormPanelSection(), diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java index 8e8e4b24e..4d7c8c251 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java @@ -38,6 +38,9 @@ public PathologyDiagnosesFormSection(String schemaName, String queryName, String addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/grid/DragDropGridPanel.js")); addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/buttons/pathologyButtons.js")); setXtype("onprc_ehr-dragdropgridpanel"); + + //Added: 10-31-2018 R.Blasa address issues with text font size + addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/Gross_Finding.css")); } // Added: 6-26-2017 R.Blasa Include tool bar at bottom grid @@ -49,6 +52,14 @@ public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) return jsonObject; } + @Override + public List getTbarButtons() + { + List result = super.getTbarButtons(); + result.add("PATH_SAVE_DRAFT"); + return result; + } + @Override public List getTbarMoreActionButtons() { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/LastHousingDemographicsProvider.java b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/LastHousingDemographicsProvider.java new file mode 100644 index 000000000..514a2c155 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/LastHousingDemographicsProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.demographics; + +import org.labkey.api.ehr.demographics.AbstractDemographicsProvider; +import org.labkey.api.ehr.demographics.AbstractListDemographicsProvider; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +// Created: 12-19-2018 R.Blasa + +public class LastHousingDemographicsProvider extends AbstractListDemographicsProvider +{ + public LastHousingDemographicsProvider(Module module) + { + super(module, "study", "LastHousingLocation", "lastlocation"); + _supportsQCState = false; + } + + protected Collection getFieldKeys() + { + Set keys = new HashSet<>(); + keys.add(FieldKey.fromString("location")); + + + return keys; + } + + @Override + public boolean requiresRecalc(String schema, String query) + { + return ("study".equalsIgnoreCase(schema) && "Housing".equalsIgnoreCase(query)) || + ("study".equalsIgnoreCase(schema) && "Death".equalsIgnoreCase(query)) || + ("study".equalsIgnoreCase(schema) && "Departure".equalsIgnoreCase(query)) || + ("ehr_lookups".equalsIgnoreCase(schema) && "cage".equalsIgnoreCase(query)); + } + +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java index 87ff4d4e7..42bf83046 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/InfantsBornAssignedNotification.java @@ -133,7 +133,7 @@ private void AssignedInfantprocess(Container c, User u, final StringBuilder msg) long total = ts.getRowCount(); if (total == 0) { - msg.append("There are no Expiring Obese Flag for today.\n"); + msg.append("There are no records of infants that were born to Assigned Animals.\n"); } else { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java index 3f16bea72..abfff83ae 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java @@ -26,12 +26,12 @@ import org.labkey.api.data.Sort; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; +import org.labkey.api.ehr.notification.AbstractEHRNotification; import org.labkey.api.module.Module; import org.labkey.api.query.FieldKey; import org.labkey.api.query.QueryService; import org.labkey.api.security.User; import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.ehr.notification.AbstractEHRNotification; import java.sql.ResultSet; import java.sql.SQLException; @@ -60,7 +60,7 @@ public String getName() @Override public String getDescription() { - return "This runs every day at 9AM, 3PM if there are treatments scheduled that have not yet been marked complete"; + return "This runs every day at 9AM, 12PM, 1PM, 2PM, 3PM if there are treatments scheduled that have not yet been marked complete"; } @Override @@ -70,12 +70,12 @@ public String getEmailSubject(Container c) } @Override - public String getCronString() {return "0 0 9,15 * * ?";} + public String getCronString() {return "0 0 9,12,13,14,15 * * ?";} @Override public String getScheduleDescription() { - return "daily at 9AM,3PM"; + return "daily at 9AM,12PM,1PM,2PM,3PM"; } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java index 8000f7958..6f1825303 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java @@ -2323,4 +2323,33 @@ public void exec(ResultSet object) throws SQLException demographics.getUpdateService().updateRows(_user, _container, toUpdate, oldKeys, null, getExtraContext()); } } + + //New blood draw validation code by LKolli, 2/1/2019 + public String verifyBloodVolume_New(String id, Date date, List> recordsInTransaction, List> weightsInTransaction, String objectId, Double quantity) + { + //Check for valid AnimalId, date and quantity + if (id == null || date == null || quantity == null) + return null; + + //Get ABV data from onprc_ehr.AvailableBloodVolume + Double maxAllowable = getABV(id); + if (maxAllowable == null) + return "Couldn't find available blood volume for AnimalId: " + id ; + + if (quantity > maxAllowable) + return "The quantity requested, " + quantity + "ml exceeds the available blood volume, " + maxAllowable + "ml for AnimalId: " + id ; + + return null; + } + + //Query the db table, onprc_ehr.AvailableBloodVolume for the max allowable blood. + //This table is populated every hour during business hours by Mathematica. + public Double getABV(String id) + { + TableInfo ti = getTableInfo("onprc_ehr", "AvailableBloodVolume"); + TableSelector ts = new TableSelector(ti, PageFlowUtil.set("ABV"), new SimpleFilter(FieldKey.fromString("Id"), id), null); + + return ts.getObject(Double.class); + } + } diff --git a/sla/resources/queries/sla/PlandProtocols.sql b/sla/resources/queries/sla/PlandProtocols.sql index ad303b132..5b81e0494 100644 --- a/sla/resources/queries/sla/PlandProtocols.sql +++ b/sla/resources/queries/sla/PlandProtocols.sql @@ -24,6 +24,9 @@ WHERE (aa.StartDate IS NULL AND aa.EndDate IS NOT NULL AND now() < aa.EndDate) OR (now() between aa.StartDate AND aa.EndDate) ) + AND + --Check for the project enddate. Added by LK on 1/16/2019 + (now() between a.StartDate AND a.EndDate) -- and filtered based on dataAccess for the given user AND ( diff --git a/sla/resources/queries/sla/ProtocolProjectsUsage.sql b/sla/resources/queries/sla/ProtocolProjectsUsage.sql index 5de540786..5adc2095b 100644 --- a/sla/resources/queries/sla/ProtocolProjectsUsage.sql +++ b/sla/resources/queries/sla/ProtocolProjectsUsage.sql @@ -1,4 +1,5 @@ + SELECT a.project as ProjectID, a.name AS Project, @@ -29,15 +30,88 @@ LEFT JOIN ( -- LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i ON p.project = i.project -- WHERE p.objectid = pd.purchaseid AND animalsreceived IS NOT NULL -- GROUP BY i.protocol,species,gender + --Changed by LK on 5/30 to get the accurate numused. +--Ignore the gender when counting the usage if the approval data gender is: "Male or Female". Count both Male and Female usage. + (SELECT i.protocol,pd.species,sum(animalsreceived) AS NumUsed + FROM sla.purchasedetails pd, sla.purchase p, Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i, + Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.sla.allowableAnimals aa1 + Where p.project = i.project AND p.objectid = pd.purchaseid + AND aa1.protocol = i.protocol AND aa1.species = pd.species AND aa1.gender = 'Male or Female' + AND animalsreceived IS NOT NULL + AND (p.orderdate between aa1.StartDate AND aa1.EndDate) AND aa1.enddate > now() + GROUP BY i.protocol, pd.species) + +) AS calc ON a.protocol = calc.protocol + AND (aa.species = calc.species OR (aa.species IS NULL AND calc.species IS NULL)) + --AND (aa.gender = calc.gender OR (aa.gender IS NULL AND calc.gender IS NULL)) + --AND (aa.strain = calc.strain OR (aa.strain IS NULL AND calc.strain IS NULL)) +WHERE + -- filter based on the current date compared with the start and end dates + ( + (aa.StartDate IS NOT NULL AND aa.EndDate IS NULL AND now() > aa.StartDate) OR + (aa.StartDate IS NULL AND aa.EndDate IS NOT NULL AND now() < aa.EndDate) OR + (aa.StartDate IS NOT NULL AND aa.EndDate IS NOT NULL AND now() between aa.StartDate AND aa.EndDate) + AND (aa.gender = 'Male or Female') + ) + AND + --Check for the project enddate. Added by LK on 1/16/2019 + (now() between a.StartDate AND a.EndDate) + -- and filtered based on dataAccess for the given user + AND + ( + (SELECT max(rowid) as expr FROM onprc_billing.dataAccess da + -- current logged in user is the dataAccess user + WHERE isMemberOf(da.userid) + -- has access to all data + AND (da.allData = true + -- has access to the specified investigatorId and the specified project (if applicable) + OR (da.investigatorId = i.rowId AND (da.project IS NULL OR da.project = a.project))) + ) IS NOT NULL + ) + +UNION ALL + +SELECT +a.project as ProjectID, +a.name AS Project, +p.external_id as eIACUCNum, +a.title as Title, +i.LastName || ', ' || i.FirstName AS PIName, +x.account as Alias, +y.projectNumber as OGAProjectNumber, +y.grantNumber as OGAGrantNumber, +f.lastname || ', ' || f.firstName as FiscalAuthorityName, +aa.Species, +aa.Gender, +aa.Strain, +aa.Allowed AS NumAllowed, +calc.NumUsed, +aa.StartDate, +aa.EndDate +FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project a +LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.protocol p ON p.protocol = a.protocol +LEFT JOIN onprc_ehr.investigators i ON i.rowId = a.investigatorId +LEFT JOIN onprc_billing.fiscalAuthorities f ON f.rowid = i.financialanalyst +LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.sla.allowableAnimals aa ON a.protocol = aa.protocol +LEFT JOIN (select * from onprc_billing.projectAccountHistory z where (z.StartDate IS NOT NULL AND z.EndDate IS NOT NULL AND now() between z.StartDate AND z.EndDate)) x ON a.project = x.project +LEFT JOIN "/onprc/admin/finance/public".onprc_billing_public.aliases y ON y.alias = x.account +LEFT JOIN ( +-- SELECT i.protocol,species,gender,sum(animalsreceived) AS NumUsed +-- FROM sla.purchasedetails pd, sla.purchase p +-- LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i ON p.project = i.project +-- WHERE p.objectid = pd.purchaseid AND animalsreceived IS NOT NULL +-- GROUP BY i.protocol,species,gender + +--Changed by LK on 5/30 to get the accurate numused. +-- Count only the usage for the "Male" or "Female" gender (SELECT i.protocol,pd.species,pd.gender,sum(animalsreceived) AS NumUsed FROM sla.purchasedetails pd, sla.purchase p, Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project i, Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.sla.allowableAnimals aa1 Where p.project = i.project AND p.objectid = pd.purchaseid - AND aa1.protocol = i.protocol AND aa1.species = pd.species AND aa1.gender = pd.gender + AND aa1.protocol = i.protocol AND aa1.species = pd.species AND aa1.gender = pd.gender AND aa1.gender <> 'Male or Female' AND animalsreceived IS NOT NULL AND (p.orderdate between aa1.StartDate AND aa1.EndDate) AND aa1.enddate > now() - --And i.project = 2167 GROUP BY i.protocol, pd.species, pd.gender) ) AS calc ON a.protocol = calc.protocol @@ -49,9 +123,12 @@ WHERE ( (aa.StartDate IS NOT NULL AND aa.EndDate IS NULL AND now() > aa.StartDate) OR (aa.StartDate IS NULL AND aa.EndDate IS NOT NULL AND now() < aa.EndDate) OR - (now() between aa.StartDate AND aa.EndDate) - --(aa.StartDate IS NOT NULL AND aa.EndDate IS NOT NULL AND now() between aa.StartDate AND aa.EndDate) + (aa.StartDate IS NOT NULL AND aa.EndDate IS NOT NULL AND now() between aa.StartDate AND aa.EndDate) + AND (aa.gender <> 'Male or Female') ) + AND + --Check for the project enddate. Added by LK on 1/16/2019 + (now() between a.StartDate AND a.EndDate) -- and filtered based on dataAccess for the given user AND ( diff --git a/sla/resources/web/sla/form/CreatePurchaseOrder.js b/sla/resources/web/sla/form/CreatePurchaseOrder.js index dad8ec453..170b2a71d 100644 --- a/sla/resources/web/sla/form/CreatePurchaseOrder.js +++ b/sla/resources/web/sla/form/CreatePurchaseOrder.js @@ -1,3 +1,4 @@ + /** * Ext component for creating the input form and species grid for collecting/updating information about * a purchase order (see createPurchaseOrder.html and updatePurchaseOrder.html for usages). @@ -41,7 +42,7 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { //}); - // add the initial form sections, start with just the protocol form if this is not an update + // add the initial form sections, start with just the protocol form if this is not an update var items = [ this.getProtocolForm(), this.getPurchaseForm(), @@ -128,8 +129,8 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { noRequestorRecord: function(form) { Ext4.get('purchaseOrderErrors').update('

' - + 'No requestor record found for your user account. Please contact an administrator to get ' - + 'this issue resolved.

'); + + 'No requestor record found for your user account. Please contact an administrator to get ' + + 'this issue resolved.

'); this.disable(); } } @@ -251,8 +252,8 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { toggleSubmitButton : function() { var protocolValid = this.getProtocolForm().isValid(), - formValid = this.getPurchaseForm().isValid(), - speciesGridValid = this.getPurchaseSpeciesGrid().isValid(); + formValid = this.getPurchaseForm().isValid(), + speciesGridValid = this.getPurchaseSpeciesGrid().isValid(); this.getSubmitButton().setDisabled(this.adminContainer == null || !protocolValid || !formValid || !speciesGridValid); }, @@ -553,13 +554,13 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { Ext4.Msg.confirm('Confirmation Message', warnMsg, function (btn) { if (btn == 'yes') - //successCallback.call(scope); + //successCallback.call(scope); this.insertPurchaseOrder(purchaseData); else this.getSubmitButton().enable(); }, this); - // this.insertPurchaseOrder(purchaseData); + // this.insertPurchaseOrder(purchaseData); }, this); } }, @@ -696,15 +697,15 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { if (value.PercentUsed > 105) { errorMsg += errorSep + 'With the current order, you have exceeded 100% plus 5% more animal usage of the approved quantity. ' + baseMsg - + ' You are not authorized to purchase any more animals at this point. If you wish to purchase more animals, please contact the IACUC committee for approval!'; + + ' You are not authorized to purchase any more animals at this point. If you wish to purchase more animals, please contact the IACUC committee for approval!'; errorSep = '

'; } else if (value.PercentUsed > 100) { warnMsg += warnSep + 'With the current order, you have exceeded 100% animal usage of the approved quantity. ' + baseMsg - + ' According to IACUC committee, you can order 5% more animals than the approved quantity without IACUC approval. ' - + 'Therefore in this order, you can order an extra ' + Math.floor(value.NumAllowed * 0.05) + ' animal(s). ' - + 'If you wish to purchase more animals, please contact the IACUC committee for approval!'; + + ' According to IACUC committee, you can order 5% more animals than the approved quantity without IACUC approval. ' + + 'Therefore in this order, you can order an extra ' + Math.floor(value.NumAllowed * 0.05) + ' animal(s). ' + + 'If you wish to purchase more animals, please contact the IACUC committee for approval!'; warnSep = '

'; } else if (value.PercentUsed == 100) @@ -809,11 +810,11 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { if (!sendNotification && this.initData != null) { var prevConfNum = this.initData.purchase['confirmationnum'], - newConfNum = newPurchaseData['confirmationnum'], - prevOrderDt = this.trimDateToYMDStr(this.initData.purchase['orderdate']), - newOrderDt = this.trimDateToYMDStr(newPurchaseData['orderdate']), - prevHousingAvail = this.initData.purchase['housingconfirmed'], - newHousingAvail = newPurchaseData['housingconfirmed']; + newConfNum = newPurchaseData['confirmationnum'], + prevOrderDt = this.trimDateToYMDStr(this.initData.purchase['orderdate']), + newOrderDt = this.trimDateToYMDStr(newPurchaseData['orderdate']), + prevHousingAvail = this.initData.purchase['housingconfirmed'], + newHousingAvail = newPurchaseData['housingconfirmed']; sendNotification = prevConfNum != newConfNum || prevOrderDt != newOrderDt; @@ -833,21 +834,21 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { Ext4.each(newPurchaseData.details, function (detailsRow) { var objectid = detailsRow['objectid'], - receiveddate = Ext4.isDate(detailsRow['receiveddate']) ? Ext4.util.Format.date(detailsRow['receiveddate'], 'Y-m-d') : this.trimDateToYMDStr(detailsRow['receiveddate']), - receivedby = detailsRow['receivedby'], - datecancelled = Ext4.isDate(detailsRow['datecancelled']) ? Ext4.util.Format.date(detailsRow['datecancelled'], 'Y-m-d') : this.trimDateToYMDStr(detailsRow['datecancelled']), - cancelledby = detailsRow['cancelledby']; + receiveddate = Ext4.isDate(detailsRow['receiveddate']) ? Ext4.util.Format.date(detailsRow['receiveddate'], 'Y-m-d') : this.trimDateToYMDStr(detailsRow['receiveddate']), + receivedby = detailsRow['receivedby'], + datecancelled = Ext4.isDate(detailsRow['datecancelled']) ? Ext4.util.Format.date(detailsRow['datecancelled'], 'Y-m-d') : this.trimDateToYMDStr(detailsRow['datecancelled']), + cancelledby = detailsRow['cancelledby']; // compare new values to previous, or if this is a new species row, check for non-null key values if (Ext4.isDefined(prevDetailsMap[objectid])) { var prevReceiveddate = this.trimDateToYMDStr(prevDetailsMap[objectid]['receiveddate']), - prevReceivedby = prevDetailsMap[objectid]['receivedby'], - prevDatecancelled = this.trimDateToYMDStr(prevDetailsMap[objectid]['datecancelled']), - prevCancelledby = prevDetailsMap[objectid]['cancelledby']; + prevReceivedby = prevDetailsMap[objectid]['receivedby'], + prevDatecancelled = this.trimDateToYMDStr(prevDetailsMap[objectid]['datecancelled']), + prevCancelledby = prevDetailsMap[objectid]['cancelledby']; sendNotification = prevReceiveddate != receiveddate || prevReceivedby != receivedby - || prevDatecancelled != datecancelled || prevCancelledby != cancelledby; + || prevDatecancelled != datecancelled || prevCancelledby != cancelledby; } else if (receiveddate != null || receivedby != null || datecancelled != null || cancelledby != null) { @@ -1059,7 +1060,21 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { "chargeType": 'SLAU', "chargeId": 5398, //Chargeableitem: ChargeName = 'SLAU Weaning Fee', ChargeID = 5398 "quantity": 1, //detailsRow['NumAnimalsReceived'], - "comment": 'SLA Weaning', + "comment": 'SLA Weaning' + }); + } + //Added by Kolli on 03-01-2019 + else if (this.initData.purchase.vendor == 'ONPRC Weaning - Self Prepared') + { + miscCharges.push({ + "date": receiveddate, + "project": newPurchaseData['project'], + "objectid": LABKEY.Utils.generateUUID(), + //"category": 'SLA Fees', + "chargeType": 'SLAU', + "chargeId": 5614, //Chargeableitem: ChargeName = 'SLAU Weaning - No Staff', ChargeID = 5398 + "quantity": 1, //detailsRow['NumAnimalsReceived'], + "comment": 'SLA Weaning - Self Prepared' }); } else @@ -1072,7 +1087,7 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { "chargeType": 'SLAU', "chargeId": 5331, //Chargeableitem: ChargeName = 'SLAU Animal Purchase', ChargeID = 5331 "quantity": 1, //detailsRow['NumAnimalsReceived'], - "comment": 'SLA Purchase billing', + "comment": 'SLA Purchase billing' }); } } @@ -1186,3 +1201,7 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { }); } }); + + + + diff --git a/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql b/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql index 19f76a089..4efde2469 100644 --- a/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql +++ b/treatmentETL/resources/queries/study/treatmentScheduleUpdate.sql @@ -1,3 +1,7 @@ +--Date 2019-03-15 +--By jonesga +--inserted missing code at line 87 + SELECT d.id, d.calculated_status, @@ -84,6 +88,7 @@ JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study."Trea ON (dr.dateOnly >= t1.dateOnly and dr.dateOnly <= t1.enddateCoalesced AND --technically the first day of the treatment is day 1, not day 0 mod(CAST(timestampdiff('SQL_TSI_DAY', CAST(t1.dateOnly as timestamp), dr.dateOnly) as integer), t1.frequency.intervalindays) = 0 + OR (t1.frequency.dayofweek is not null And t1.frequency.intervalindays is null And dr.DayOfWeek in (select k.value from onprc_ehr.Frequency_DayofWeek k where k.FreqKey = t1.frequency.rowid )) ) LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.treatment_times tt ON (tt.treatmentid = t1.objectid) From 10e76801136ed67d19dc95fc89235913c61d318e Mon Sep 17 00:00:00 2001 From: Binal Date: Tue, 6 Oct 2020 14:51:54 -0700 Subject: [PATCH 04/49] Merge from onprc19.1 r.63282 --- .../views/printableComplianceReports.html | 8 +++--- .../clinPathRun_ExemptCharges.sql | 25 +++++++++++++++++++ .../queries/onprc_billing/virologyAliases.sql | 6 ++--- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 1 + 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 onprc_billing/resources/queries/onprc_billing/clinPathRun_ExemptCharges.sql diff --git a/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html index 50dc0cd86..7c28640ab 100644 --- a/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html +++ b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html @@ -110,10 +110,10 @@ 'rs:ClearSession': true, 'rs:Command': 'render' }); - + //Modified: 1-17-2019 R.Blasa var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'EmployeeComplianceXMLReport'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Compliance/EmployeeComplianceXMLReport'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); @@ -183,10 +183,10 @@ 'rs:ClearSession': true, 'rs:Command': 'render' }); - + //Modified: 1-17-2019 R.Blasa var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); - ssrsFolder = '/' + ssrsFolder + '/' + 'EmployeeComplianceXMLReport'; + ssrsFolder = '/' + ssrsFolder + '/' + 'Compliance/EmployeeComplianceXMLReport'; url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); diff --git a/onprc_billing/resources/queries/onprc_billing/clinPathRun_ExemptCharges.sql b/onprc_billing/resources/queries/onprc_billing/clinPathRun_ExemptCharges.sql new file mode 100644 index 000000000..a2caf8a26 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/clinPathRun_ExemptCharges.sql @@ -0,0 +1,25 @@ +SELECT c.Id, +c.date, +c.project, +c.servicerequested, +c.chargetype, +c.sampletype, +c.tissue, +c.collectionMethod, +c.method, +c.remark, +c.type, +c.instructions, +c.units, +c.taskid, +c.performedby, +c.requestid, +c.history, +c.isAssignedAtTime, +c.isAssignedToProtocolAtTime, +c.enteredSinceVetReview, +c.QCState, +c.objectID as sourceRecord, +c.datefinalized as billingDate +FROM study.clinpathRuns c left outer join "/ONPRC/ADMIN/Finance".lists.Labfee_NoChargeProjects p on c.project.DisplayName = p.project +where (p.dateDisabled is null and p.project is Null) \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql b/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql index bc8c7d915..fa79937f5 100644 --- a/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql +++ b/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql @@ -1,7 +1,7 @@ SELECT alias, alias + ' - ' + COALESCE(investigatorName, 'N/A') as aliasPI FROM "/onprc/admin/finance/public".onprc_billing_public.aliases --WHERE a.projectStatus in ('Active', 'Partial Setup', 'No Cost Ext', 'Preaward') OR a.alias in ('68119000', '46050050') -WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate > now() )) OR alias in ('68119000', '46050050','46030010', '61247550') +--WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate > now() )) OR alias in ('68119000', '46050050','46030010', '61247550') --Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')} ---WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate > now() )) ---OR alias in (Select alias from Special_Aliases Where category like 'Virology') +WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate > now() )) +OR alias in (Select alias from "/onprc/admin/finance".lists.Special_Aliases Where category like 'Virology') diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index c01cd1e79..d701141ac 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -297,6 +297,7 @@ private void registerEHRResources() { // SSRS is picky about the URI-encoding of the query parameters @Override + //Modified: 1-17-2019 R.Blasa public String toString() { return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render"; From 80aecf77ad4fa11c00d3c823eec25701df109de4 Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 00:31:10 -0700 Subject: [PATCH 05/49] Merge from onprc19.1 r.63328 to 64381 --- .../labworkFeeDefinition.query.xml | 59 +++++++++++++++++++ .../resources/schemas/onprc_billing.xml | 12 +++- .../Vet_assignmentMissingSummary.sql | 6 ++ .../vet_assignmenMissingData.query.xml | 30 ++++++++++ .../onprc_ehr/vet_assignmentMissingData.sql | 52 ++++++++++++++++ .../vet_assignmentMissingLink.query.xml | 30 ++++++++++ .../onprc_ehr/vet_assignmentMissingLink.sql | 6 ++ .../vet_assignment_summary.query.xml | 2 +- .../queries/study/birth_resourceDam.sql | 14 +++++ .../queries/study/demographicsAssignedVet.sql | 4 +- .../resources/queries/study/tmbBirth.sql | 41 +++++++++++++ onprc_ehr/resources/queries/study/tmbDam.sql | 10 ++++ .../queries/study/vet_assignedResearch.sql | 16 +++++ .../queries/study/vet_assignedResource.sql | 11 ++++ .../study/vet_assignmentDemographics.sql | 42 +++++++------ .../sqlserver/onprc_ehr-12.395-12.396.sql | 3 +- .../sqlserver/onprc_ehr-12.405-12.406.sql | 4 +- .../sqlserver/onprc_ehr-12.406-12.407.sql | 2 - .../sqlserver/onprc_ehr-12.407-12.408.sql | 2 - .../sqlserver/onprc_ehr-12.408-12.409.sql | 2 - .../resources/views/serviceRequests.view.xml | 5 +- onprc_ehr/resources/views/vetReview.html | 4 +- .../model/sources/ClinicalEncounters.js | 2 +- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 5 ++ .../buttons/CreateNecropsyRequestButton.java | 2 +- .../dataentry/NecropsyRequestForm.java | 4 +- .../NecropsyRequestInfoFormSection.java | 8 ++- 27 files changed, 335 insertions(+), 43 deletions(-) create mode 100644 onprc_billing/resources/queries/onprc_billing/labworkFeeDefinition.query.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/Vet_assignmentMissingSummary.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/vet_assignmenMissingData.query.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingData.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.query.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.sql create mode 100644 onprc_ehr/resources/queries/study/birth_resourceDam.sql create mode 100644 onprc_ehr/resources/queries/study/tmbBirth.sql create mode 100644 onprc_ehr/resources/queries/study/tmbDam.sql create mode 100644 onprc_ehr/resources/queries/study/vet_assignedResearch.sql create mode 100644 onprc_ehr/resources/queries/study/vet_assignedResource.sql diff --git a/onprc_billing/resources/queries/onprc_billing/labworkFeeDefinition.query.xml b/onprc_billing/resources/queries/onprc_billing/labworkFeeDefinition.query.xml new file mode 100644 index 000000000..8061a69f0 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/labworkFeeDefinition.query.xml @@ -0,0 +1,59 @@ + + + + + Labwork Charges + + + + Row Id + + + Service/Panel Name + false + + /ONPRC/EHR + ehr_lookups + labwork_services + servicename + + + + Charge Type + true + true + + /ONPRC/EHR + ehr_lookups + labworkChargeType + value + + + + Charge Id + false + + + Is Active? + true + + + Start Date + false + Date + + + End Date + false + Date + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/onprc_billing/resources/schemas/onprc_billing.xml b/onprc_billing/resources/schemas/onprc_billing.xml index bf0d85a0a..0e9b9dddb 100644 --- a/onprc_billing/resources/schemas/onprc_billing.xml +++ b/onprc_billing/resources/schemas/onprc_billing.xml @@ -1,4 +1,4 @@ - + Charge Rates @@ -97,7 +97,7 @@ Service Center A code used to categorize these items by department, primarily used when exporting or communicating with external billing systems. Similar to itemCode - + Allow Custom Unit Cost? @@ -541,6 +541,7 @@ Housing Type false + EHR ehr_lookups housingTypes rowid @@ -551,6 +552,7 @@ Housing Definition false + EHR ehr_lookups housingDefinition rowid @@ -921,6 +923,7 @@ Charge Type false + EHR ehr_lookups procedureChargeType value @@ -930,6 +933,7 @@ Assisting Staff true + EHR ehr_lookups procedureChargeType value @@ -976,6 +980,7 @@ SNOMED Code false + EHR ehr_lookups snomed code @@ -986,6 +991,7 @@ If provided, only medications using this route will be billed. Can be left blank for all routes. false + EHR ehr_lookups routes route @@ -1244,6 +1250,7 @@ Service/Panel Name false + /ONPRC/EHR ehr_lookups labwork_services servicename @@ -1254,6 +1261,7 @@ true true + /ONPRC/EHR ehr_lookups labworkChargeType value diff --git a/onprc_ehr/resources/queries/onprc_ehr/Vet_assignmentMissingSummary.sql b/onprc_ehr/resources/queries/onprc_ehr/Vet_assignmentMissingSummary.sql new file mode 100644 index 000000000..c37cceb8b --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/Vet_assignmentMissingSummary.sql @@ -0,0 +1,6 @@ +SELECT m.MissingItem, +Count(m.Item) As TotalMissing +--m.Vet_AssignedItem, +--m.totalNHps +FROM vet_assignmentMissingData m +group by m.missingItem \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignmenMissingData.query.xml b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmenMissingData.query.xml new file mode 100644 index 000000000..e4bb5e01c --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmenMissingData.query.xml @@ -0,0 +1,30 @@ + + + + + +
+ Vet Assignment Missing Item Summary + + + /query/executeQuery.view? + schemaName=onprc_ehr& + queryName=Vet_assignmentMissingSummary& + query.MissingItem~eq=${MissingItem}& + + + +
+
+ + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingData.sql b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingData.sql new file mode 100644 index 000000000..da320d1c3 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingData.sql @@ -0,0 +1,52 @@ +Select +'Research Protocol_Missing' as MissingItem, +a.project.protocol.displayName as Item, +v.protocol.displayName as Vet_AssignedItem, +Count(a.participantId) as totalNHps +from study.assignment a left outer join vet_assignment v on a.project.protocol = v.protocol.protocol +where a.project.use_category = 'Research' and a.enddate is null and v.protocol.displayName is null +group by a.project.protocol.displayname,v.protocol.displayName + +Union + +Select +'Resource Protocol_Missing' as MissingItem, +a.project.protocol.displayName as Item, +v.protocol.displayName as Vet_AssignedItem, +Count(a.participantId) as totalNHps +from study.assignment a left outer join vet_assignment v on a.project.protocol = v.protocol.protocol +where a.project.use_category != 'Research'and a.enddate is null and v.protocol.displayName is null +group by a.project.protocol.displayname,v.protocol.displayName +Union + +Select +'Area_Missing' as MissingItem, +a.area as Item, +v.area as Vet_AssignedItem, +Count(h.ID) as TotalNHPS +from ehr_lookups.areas a left outer join vet_assignment v on a.area = v.area + left outer join study.housing h on h.room.area = a.area +where v.area is null and h.enddate is null +group by a.area,v.area + + +Union + +Select +'Room_Missing' as MissingItem, +r.room as Item, +v.room as Vet_AssignedItem, +Count(h.id) as totalNHPs +from ehr_lookups.rooms r left outer join vet_assignment v on r.room = v.room + left outer join study.housing h on h.room = r.room and h.enddate is null +where v.room is null and r.area not in (Select v1.area from vet_assignment v1 where v1.area = r.area) +group by r.room,v.room + +union + +Select +'NHP No Vet', +v.id, +v.assignedVet, +0 +from study.demographicsAssignedVet v where v.assignedvet is null diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.query.xml b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.query.xml new file mode 100644 index 000000000..e4bb5e01c --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.query.xml @@ -0,0 +1,30 @@ + + + + + + + Vet Assignment Missing Item Summary + + + /query/executeQuery.view? + schemaName=onprc_ehr& + queryName=Vet_assignmentMissingSummary& + query.MissingItem~eq=${MissingItem}& + + + +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.sql b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.sql new file mode 100644 index 000000000..c37cceb8b --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignmentMissingLink.sql @@ -0,0 +1,6 @@ +SELECT m.MissingItem, +Count(m.Item) As TotalMissing +--m.Vet_AssignedItem, +--m.totalNHps +FROM vet_assignmentMissingData m +group by m.missingItem \ No newline at end of file diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml index e5e46d5ff..8210a6a70 100644 --- a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml @@ -3,7 +3,7 @@ Vet Assignment - + org.labkey.ehr.table.DefaultEHRCustomizer diff --git a/onprc_ehr/resources/queries/study/birth_resourceDam.sql b/onprc_ehr/resources/queries/study/birth_resourceDam.sql new file mode 100644 index 000000000..53bd493fd --- /dev/null +++ b/onprc_ehr/resources/queries/study/birth_resourceDam.sql @@ -0,0 +1,14 @@ +SELECT b.Id, +b.date, +b.date_type, +b.birth_condition, +b.room, +b.cage, +b.dam, +b.gender, +b.species, +a.project.use_category, +a.project as DammProject + +FROM birth b join study.assignment a on b.dam = a.id +where a.project.use_Category not in ('Research','Aging Resources') \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql index 15e925a27..1e79bb558 100644 --- a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql +++ b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql @@ -8,7 +8,7 @@ d.room, d.CaseVet, d.protocol, Case - + when d.DeceaseDAssignedVet is not null then d.DeceaseDAssignedVet when d.caseVet is not null then d.CaseVet when p3.userId is not null then v1.userId.displayName when p4.userId is not null then v2.userId.DisplayName @@ -26,7 +26,7 @@ Case End as AssignedVet, Case - + when d.DeceaseDAssignedVet is not null then 'Deceased or Shipped NHP' when d.caseVet is not null then 'Open Case' When p3.userId is not null then 'Protocol Room Priority' When p4.userId is not null then 'Protocol Area Priority' diff --git a/onprc_ehr/resources/queries/study/tmbBirth.sql b/onprc_ehr/resources/queries/study/tmbBirth.sql new file mode 100644 index 000000000..894ff4738 --- /dev/null +++ b/onprc_ehr/resources/queries/study/tmbBirth.sql @@ -0,0 +1,41 @@ +--created 8/22/2018 by jonesga +--purpose to identify dual assigned animals for use with lease fee queries + +--We are now showing TMB assignments +--need to determine whether the Dam was assigned to the +--We are now showing TMB assignments +--need to determine whether the Dam was assigned to the +--Update 3/11/2019 Added to Test +Select distinct +b.id, +b.date, +--going to want to add the NonTMB Assignment data to the project details +a.project, +a.date as InfantAssignmentDate, +--(Select a3.id from study.assignment a3 where a3.id = b.dam and a3.project = a.project and a3.date <= b.date and a3.enddate > b.date or a3.enddate is null and a3.project <> 559) as DamAssignment, +b.dam, +t.id as TMBDam, +t.date as TMBAssignedDate, +t.endDate as TMBEndDate, + +da.dualassignment, +da.dualstartDate, +da.dualEndDate, + +t.enddate as RemovalDate, +--determine how the dam was assigned at the time of birth +Case + When a.project is not Null and b.dam in (Select a2.id from study.assignment a2 where a2.id = b.dam and a2.project = a.project and a2.date <= b.date and a2.enddate > b.date or a2.enddate is null) then 'Dam on Project' + When b.dam in (Select a2.id from study.assignment a2 where a2.id = b.dam and a2.project <> a.project and a2.date <= b.date and a2.enddate > b.date or a2.enddate is null) then 'Dam TMB Only' + --When then ' Dam TMB Only' + else 'Undetermined' + end as TMBDamStatus +-- WHEN MOM NOT on other project except TMB we will look for infant assignment within 30 days of birth to credit otherwisse it is P51 +--Determine if animal was not immediately assigned to a Research project and then assigned to a Research project within 30 days of its birth + + +from study.birth b join study.tmbdam t on b.dam = t.id + left join study.assignment a on (a.id = b.id and a.dateOnly = b.dateOnly) + left outer join study.dualAssigned da on (da.id = b.dam and a.project = da.dualAssignment + and (da.dualstartDate < b.date and da.dualendDate > b.date)) +where b.date > t.date \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/tmbDam.sql b/onprc_ehr/resources/queries/study/tmbDam.sql new file mode 100644 index 000000000..8f1cc7ae9 --- /dev/null +++ b/onprc_ehr/resources/queries/study/tmbDam.sql @@ -0,0 +1,10 @@ +--Update 3/11/2019 Added to Test + +SELECT a.Id, +a.id.demographics.gender, +a.project, +a.date, +a.projectedRelease, +a.enddate + +FROM assignment a where a.project = 559 and enddate is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignedResearch.sql b/onprc_ehr/resources/queries/study/vet_assignedResearch.sql new file mode 100644 index 000000000..63027aedf --- /dev/null +++ b/onprc_ehr/resources/queries/study/vet_assignedResearch.sql @@ -0,0 +1,16 @@ +--20190410 - changed to address no assigned vet for protocol in research update1 +--Iss was this was not loaded at the prodctuib level + +SELECT a.Id, +a.project, +a.project.use_category, +a.project.protocol, +a.date, +a.projectedRelease, +a.enddate, +a.assignCondition, +'Research Assigned' as ProtocolType, +v.protocol as VetAssignedProtocol +FROM study.assignment a left outer join "/onprc/ehr".onprc_ehr.vet_assignment v on a.project.protocol = v.protocol +where ((a.date <= Now() and a.enddate is null) and (a.project.use_category = 'Research')) +and v.protocol is not null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignedResource.sql b/onprc_ehr/resources/queries/study/vet_assignedResource.sql new file mode 100644 index 000000000..c5c820e7c --- /dev/null +++ b/onprc_ehr/resources/queries/study/vet_assignedResource.sql @@ -0,0 +1,11 @@ +SELECT a.Id, +a.project, +a.project.use_category, +a.project.protocol, +a.date, +a.projectedRelease, +a.enddate, +a.assignCondition, +'Resource Assigned' as ProtocolType +FROM study.assignment a +where ((a.date <= Now() and a.enddate is null) and (a.project.use_category != 'Research')) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql b/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql index 24d4e6d6c..94f87d60f 100644 --- a/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql +++ b/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql @@ -1,5 +1,7 @@ --Reviewed 2/7/2019 to update from vet_AssignmentDemographics_new --Is the depenency for vet_assignmentSelect +--Reviewed 2/7/2019 to update from vet_AssignmentDemographics_new +--Is the depenency for vet_assignmentSelect SELECT Distinct @@ -10,15 +12,16 @@ d.species, d.geographic_origin, d.birth, d.death, +d.lastDayatCenter, h.room.area, h.room, d.calculated_status, TimeStampAdd('SQL_TSI_YEAR', -1,Now()) as LastYear, ---n.assignedVet as DeceaseDAssignedVet, +n.assignedVet as DeceaseDAssignedVet, c.vetNames as CaseVet, c.category, CASE - -- WHEN (n.status IS NOT null) THEN 'DECEASED NHP' + WHEN (n.id IS NOT null) THEN 'DECEASED or SHIPPED NHP' WHEN (c.id IS NOT NULL) THEN 'Active Case' WHen r1.id is not null then 'Research Assigned' WHen r2.id is not null then 'Resource Assigned' @@ -44,18 +47,21 @@ Case FROM study.demographics d --Handles Deceased NHPs -/* + LEFT JOIN ( - Select - n.id, - vd.assignedVet, - 'Deceased' as status - from study.deaths n join study.vetAssignedDeceased vd on n.Id = vd.id - where n.date > TimeStampAdd('SQL_TSI_month', -3,Now())) + select r.id, r.assignedVet + + + from study.demographics d1 join study.clinremarks r on d1.id = r.id + where d1.lastdayatCenter > TimeStampAdd('SQL_TSI_month', -12,Now()) + and r.date = (Select Max(r1.date) from study.clinremarks r1 where r1.id = d1.id)) + + + n on (n.Id =d.id) -*/ ---Handles NHPS with active Cases + +--Handles NHPS with open Cases LEFT JOIN ( SELECT @@ -65,18 +71,20 @@ LEFT JOIN ( c.date FROM study.cases c - WHERE (c.category != 'Behavior' and c.enddateCoalesced >= curdate() ) - and c.allProblemCategories not like 'Routine%' + WHERE (c.category not in ('Behavior','Surgery') + and c.IsOpen = 'true') + --and c.enddateCoalesced >= curdate() ) + --and c.allProblemCategories not like 'Routine%' GROUP BY c.Id,c.category,c.date,c.assignedvet.DisplayName ) c ON (c.Id = d.Id) --Review for Assigned Animals Left Join study.vet_AssignedResearch r1 on d.id = r1.id -Left Join study.vet_assignedResource r2 on d.id = r2.id and r2.id not in (Select r3.id from study.vet_AssignedResearch r3) +Left Join study.vet_assignedResource r2 on d.id = r2.id --and r2.id not in (Select r3.id from study.vet_AssignedResearch r3) Left Join study.housing h on h.id = d.id and (h.enddateTimeCoalesced >= now()) --report only on animals that are alive or deceased in last year where - (d.calculated_Status = 'Alive') - and d.id not Like '[A-Z]%' - --and (d.death is null or d.death > TimeStampAdd('SQL_TSI_MONTH', -2,Now()))) \ No newline at end of file + (d.lastDayAtCenter is Null or d.lastDayAtCenter > TimeStampAdd('SQL_TSI_MONTH', -12,Now())) + --(d.calculated_Status = 'Alive' OR (d.death is null or d.death > TimeStampAdd('SQL_TSI_MONTH', -2,Now())) + and d.id not Like '[A-Z]%' \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql index e63d2705f..de37c303a 100644 --- a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.395-12.396.sql @@ -16,13 +16,12 @@ * SQL 2014 DB for Labkey-gj */ -GO /****** Object: StoredProcedure [onprc_ehr].[etl1_eIACUCtoPRIMEProcessing] Script Date: 2/7/2018 2:01:46 PM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -Create PROCEDURE onprc_ehr.etl.Step1eIACUCtoPRIMEProcessing +Create PROCEDURE onprc_ehr.etlStep1eIACUCtoPRIMEProcessing AS diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql index b23ecde03..34de36722 100644 --- a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.405-12.406.sql @@ -14,14 +14,12 @@ * */ -USE [Labkey] -GO /****** Object: StoredProcedure [onprc_ehr].[etl1_eIACUCtoPRIMEProcessing] Script Date: 2/7/2018 2:01:46 PM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -CREATE PROCEDURE [onprc_ehr.etl.Step1eIACUCtoPRIMEProcessing] +CREATE PROCEDURE [onprc_ehr.etlStep1eIACUCtoPRIMEProcessing] AS diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql index db4199aa8..6df9eecca 100644 --- a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.406-12.407.sql @@ -14,8 +14,6 @@ * */ -USE [Labkey] -GO /****** Object: StoredProcedure [onprc_ehr].[etl.Step1A_eIACUCtoPublicAction] Script Date: 2/7/2018 2:04:29 PM ******/ SET ANSI_NULLS ON GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql index 89554b8cb..810adaeff 100644 --- a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.407-12.408.sql @@ -14,8 +14,6 @@ * */ -USE [Labkey] -GO /****** Object: StoredProcedure [onprc_ehr].[etl3_insertToEhr_Protocol] Script Date: 2/7/2018 2:30:52 PM ******/ SET ANSI_NULLS ON GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql index 418eaa068..0b59e6c0a 100644 --- a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-12.408-12.409.sql @@ -14,8 +14,6 @@ * */ -USE [Labkey] -GO /****** Object: StoredProcedure [onprc_ehr].[etl2_update_ehrProtocol] Script Date: 2/7/2018 2:29:18 PM ******/ SET ANSI_NULLS ON GO diff --git a/onprc_ehr/resources/views/serviceRequests.view.xml b/onprc_ehr/resources/views/serviceRequests.view.xml index 9b8d147c5..6e234cf19 100644 --- a/onprc_ehr/resources/views/serviceRequests.view.xml +++ b/onprc_ehr/resources/views/serviceRequests.view.xml @@ -1,6 +1,7 @@ - + - + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/vetReview.html b/onprc_ehr/resources/views/vetReview.html index 3020e606f..f70108950 100644 --- a/onprc_ehr/resources/views/vetReview.html +++ b/onprc_ehr/resources/views/vetReview.html @@ -26,7 +26,9 @@ 'Each animal is assigned to a vet, using a series of rules. Vets can be assigned to either an IACUC protocol, an area, or a room. ' + 'To determine the assigned vet for each animal, the vet is preferentially selected based on IACUC assignment, then by room, and finally by area. ' + '
  • Click here to view a list of vets assigned to living animals
  • ' + - '
  • Click here to view the rules governing vet assignment
  • ', + '
  • Click here to view the rules governing vet assignment
  • ' + + '
  • Click here to view issues with vet assignmenta
  • ', + style: 'padding-bottom: 20px;', border: false },{ diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalEncounters.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalEncounters.js index fa761e834..639b9c85b 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalEncounters.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ClinicalEncounters.js @@ -15,4 +15,4 @@ EHR.model.DataModelManager.registerMetadata('ClinicalEncounters', { } } } -}); \ No newline at end of file +}); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index d701141ac..974244859 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -560,6 +560,11 @@ public String toString() EHRService.get().registerHistoryDataSource(new org.labkey.api.ehr.history.DefaultAnimalRecordFlagDataSource(this)); EHRService.get().registerHistoryDataSource(new ONPRCClinicalRemarksDataSource(this)); + EHRService.get().registerMoreActionsButton(new CreateNecropsyRequestButton(this), "study", "encounters"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "encounters"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "tissue_samples"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "organ_weights"); + EHRService.get().registerOptionalClinicalHistoryResources(this); EHRService.get().registerLabworkType(new ONPRCUrinalysisLabworkType(this)); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java index 508863168..2089a853e 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java @@ -10,6 +10,6 @@ public class CreateNecropsyRequestButton extends CreateTaskFromRecordsButton public CreateNecropsyRequestButton(Module owner) { super(owner, "Create Necropsy Request From Selected", "ONPRC_EHR.window.CreateNecropsyRequestWindow.createTaskFromRecordHandler(dataRegionName, '" + NecropsyFormType.NAME + "')"); - setClientDependencies(ClientDependency.supplierFromPath("onprc_ehr/window/CreateNecropsyRequestWindow.js")); + setClientDependencies(ClientDependency.fromPath("onprc_ehr/window/CreateNecropsyRequestWindow.js")); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java index 131865f8b..6375fde79 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java @@ -26,8 +26,8 @@ public NecropsyRequestForm(DataEntryFormContext ctx, Module owner) new SimpleFormSection("study", "tissue_samples", "Tissue Samples", "onprc_ehr-dragdropgridpanel"), new SimpleFormSection("study", "organ_weights", "Organ Weights", "onprc_ehr-dragdropgridpanel") )); - addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/grid/DragDropGridPanel.js")); - addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/ClinicalEncounters.js")); + addClientDependency(ClientDependency.fromPath("onprc_ehr/grid/DragDropGridPanel.js")); + addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/ClinicalEncounters.js")); for (FormSection s : getFormSections()) s.addConfigSource("ClinicalEncounters"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestInfoFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestInfoFormSection.java index d3ab7e041..7b2db6847 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestInfoFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestInfoFormSection.java @@ -9,10 +9,12 @@ public class NecropsyRequestInfoFormSection extends RequestFormSection protected Integer maxItemsPerColumn = 3; @Override - public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) { + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { JSONObject ret = super.toJSON(ctx, includeFormElements); - if ( maxItemsPerColumn != null ) { + if (maxItemsPerColumn != null) + { // Make the form appear in two columns JSONObject formConfig = new JSONObject(ret.get("formConfig")); formConfig.put("maxItemsPerCol", maxItemsPerColumn); @@ -21,4 +23,4 @@ public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) return ret; } -} \ No newline at end of file +} From 58dbc53b0680b9c5834bd761b1c8c01c4d6ae07a Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 00:42:15 -0700 Subject: [PATCH 06/49] Merge from onprc19.1 r.64647 --- .../Measles45DayAlert.query.xml | 49 +++++ .../EHR_ComplianceDB/Measles45DayAlert.sql | 47 +++++ .../EHR_ComplianceDB/employees.query.xml | 30 +++ .../EHR_ComplianceDB/employees/.qview.xml | 27 +++ .../EHR_ComplianceDB/requirements.query.xml | 23 +++ .../EHR_ComplianceDB/requirements/.qview.xml | 8 + .../resources/views/begin.html | 5 +- .../views/printableComplianceReports.html | 185 ++++++++--------- onprc_billing/resources/etls/ogaSynch2019.xml | 67 +++++++ .../resources/etls/ogaSynchDataOnly.xml | 30 +++ .../resources/etls/ogaSynchOnlyUAT.xml | 30 +++ .../LeaseFeeReleaseAdjustment.sql | 80 ++++++++ .../onprc_billing/LeaseFee_Demographics.sql | 97 +++++++++ .../onprc_billing/LeaseFee_LeaseType.sql | 162 +++++++++++++++ .../queries/onprc_billing/aliases/.qview.xml | 4 +- .../onprc_billing/grantProjects/.qview.xml | 1 - .../onprc_billing/invoiceditems.query.xml | 185 +++++++++++++++++ .../queries/onprc_billing/labworkFeeRates.sql | 11 +- .../onprc_billing/leaseFee_RateReview.sql | 60 ++++++ .../lease_ObeseInfant_HFDDam.sql | 9 + .../onprc_billing/lease_dayLeaseAdult.sql | 19 ++ .../onprc_billing/leasefee_leasetypeTest.sql | 163 +++++++++++++++ .../onprc_billing/leasefee_rateData.sql | 181 +++++++++++++++++ .../leasefeereleaseAdjustment1.sql | 73 +++++++ .../queries/onprc_billing/miscChargesFees.sql | 1 + .../perDiemFeeDefinition.query.xml | 34 ++++ .../queries/onprc_billing/procedureFees.sql | 3 +- .../queries/onprc_billing/virologyAliases.sql | 4 +- .../resources/views/financeManagement.html | 10 +- .../onprc_billing/ONPRC_BillingModule.java | 9 +- .../NIHIndustryRates.query.xml | 22 +- .../NIHRateConfig.query.xml | 19 +- .../NIHRateSheet.query.xml | 21 +- .../NIHRates_ReducedFA.query.xml | 18 +- .../resources/etls/drugAdministration.xml | 34 ++++ .../resources/queries/ehr/snomed_tags.js | 6 + .../ehr_lookups/behavior_Types_Current.sql | 4 + .../onprc_ehr/vet_assignmnetMissingLink.sql | 6 + .../queries/study/AssignmentTypes.sql | 5 + .../queries/study/CTACType_values.sql | 1 + .../queries/study/CTContrastType_values.sql | 1 + .../queries/study/Clinical Remarks.js | 89 --------- .../queries/study/ClinicalCases_Open.sql | 17 ++ .../queries/study/InfantsBorntoAssigned.sql | 19 ++ .../queries/study/NMRadioisotope_values.sql | 1 + .../queries/study/PETRadioisotope_values.sql | 1 + .../ProtocolHousingSummary_Species.query.xml | 15 ++ .../study/ProtocolHousingSummary_Species.sql | 25 +++ .../ProtocolHousingSummary_Species/.qview.xml | 5 + .../queries/study/TBObservationsReport.sql | 30 +++ .../study/TBObservationsReport/.qview.xml | 20 ++ .../queries/study/TBTestEnounters.sql | 25 +++ .../study/TBTestSerologyLabResults.sql | 36 ++++ .../study/TBTestSerologyLabResults/.qview.xml | 22 ++ .../queries/study/assignment.query.xml | 108 ++++++++++ .../queries/study/assignment/.qview.xml | 1 + .../demograohics_assignedVetNotification.sql | 11 + .../queries/study/demographicsAssignedVet.sql | 41 ++-- .../study/demographicsAssignedVet/.qview.xml | 22 +- .../demographics_Vet_Assignment_Alert.sql | 11 + .../study/lease_ObeseInfant_HFDDam.sql | 9 + .../study/mostRecentObservationsForCase.sql | 10 +- .../queries/study/urinalysisPivot.sql | 10 +- .../datasets/datasets_metadata.xml | 3 + onprc_ehr/resources/schemas/onprc_ehr.xml | 4 +- .../scripts/onprc_ehr/onprc_triggers.js | 84 +++++--- onprc_ehr/resources/views/begin.html | 6 +- onprc_ehr/resources/views/onprcMenu.html | 53 ++--- .../resources/views/protocolDetails.html | 13 ++ onprc_ehr/resources/views/vetReview.html | 4 +- .../model/sources/ResearchProcedures.js | 7 +- .../resources/web/onprc_ehr/onprcReports.js | 59 +++++- .../onprc_ehr/panel/ArrivalDataEntryPanel.js | 45 +++++ .../labkey/onprc_ehr/ONPRC_EHRController.java | 2 + .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 41 ++-- .../onprc_ehr/dataentry/ArrivalFormType.java | 8 +- .../ColonyAlertsNotification.java | 19 +- .../ProjectAlertsNotification.java | 73 +++++++ .../TreatmentAlertsPostOpsNotification.java | 8 +- ...eatmentAlertsPostOpsNotificationThird.java | 189 ++++++++++++++++++ .../notification/VetReviewNotification.java | 26 ++- .../query/ONPRC_EHRTriggerHelper.java | 133 +++++++++++- .../onprc_ehr/table/ONPRC_EHRCustomizer.java | 67 +++++++ sla/resources/queries/sla/PlandProtocols.sql | 3 +- .../web/sla/form/CreatePurchaseOrder.js | 5 +- .../web/sla/form/PurchaseOrderForm.js | 2 +- .../web/sla/form/PurchaseSpeciesGrid.js | 2 +- 87 files changed, 2748 insertions(+), 380 deletions(-) create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.query.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.sql create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees.query.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees/.qview.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements.query.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml create mode 100644 onprc_billing/resources/etls/ogaSynch2019.xml create mode 100644 onprc_billing/resources/etls/ogaSynchDataOnly.xml create mode 100644 onprc_billing/resources/etls/ogaSynchOnlyUAT.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/invoiceditems.query.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/lease_ObeseInfant_HFDDam.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/lease_dayLeaseAdult.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leasefee_leasetypeTest.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leasefeereleaseAdjustment1.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/perDiemFeeDefinition.query.xml create mode 100644 onprc_ehr/resources/etls/drugAdministration.xml create mode 100644 onprc_ehr/resources/queries/ehr_lookups/behavior_Types_Current.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/vet_assignmnetMissingLink.sql create mode 100644 onprc_ehr/resources/queries/study/AssignmentTypes.sql create mode 100644 onprc_ehr/resources/queries/study/CTACType_values.sql create mode 100644 onprc_ehr/resources/queries/study/CTContrastType_values.sql delete mode 100644 onprc_ehr/resources/queries/study/Clinical Remarks.js create mode 100644 onprc_ehr/resources/queries/study/ClinicalCases_Open.sql create mode 100644 onprc_ehr/resources/queries/study/NMRadioisotope_values.sql create mode 100644 onprc_ehr/resources/queries/study/PETRadioisotope_values.sql create mode 100644 onprc_ehr/resources/queries/study/ProtocolHousingSummary_Species.query.xml create mode 100644 onprc_ehr/resources/queries/study/ProtocolHousingSummary_Species.sql create mode 100644 onprc_ehr/resources/queries/study/ProtocolHousingSummary_Species/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/TBObservationsReport.sql create mode 100644 onprc_ehr/resources/queries/study/TBObservationsReport/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/TBTestEnounters.sql create mode 100644 onprc_ehr/resources/queries/study/TBTestSerologyLabResults.sql create mode 100644 onprc_ehr/resources/queries/study/TBTestSerologyLabResults/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/assignment.query.xml create mode 100644 onprc_ehr/resources/queries/study/demograohics_assignedVetNotification.sql create mode 100644 onprc_ehr/resources/queries/study/demographics_Vet_Assignment_Alert.sql create mode 100644 onprc_ehr/resources/queries/study/lease_ObeseInfant_HFDDam.sql create mode 100644 onprc_ehr/resources/web/onprc_ehr/panel/ArrivalDataEntryPanel.js create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/ProjectAlertsNotification.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.query.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.query.xml new file mode 100644 index 000000000..dd4d22255 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.query.xml @@ -0,0 +1,49 @@ + + + +
    + Measles 45 Day Overdue Report + + + true + + ehr_compliancedb + employees + employeeId + + + + Requirement Name + + ehr_compliancedb + requirements + requirementName + + ALWAYS_OFF + + + + + + + + + E3170D + + + + + + FBEC5D + + + + + Is Required? + ALWAYS_OFF + + +
    +
    + + diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.sql b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.sql new file mode 100644 index 000000000..ee9aeb1de --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/Measles45DayAlert.sql @@ -0,0 +1,47 @@ +SELECT + emp.employeeid, + emp.Name, + emp.email, + emp.unit, + emp.category, + emp.location, + emp.majorudds, + emp.notes, + emp.requirementname, + --c.date, + Case + When (c.requirementname is null) Then emp.date + When (c.requirementname is not null) Then c.date + ELSE '' + End AS DateCompleted, + emp.comment, + emp.trainer, + Case + When (c.requirementname is null) Then TIMESTAMPDIFF('SQL_TSI_DAY', emp.date, now()) + When (c.requirementname is not null) Then '-1' + ELSE '' + End as DaysOverDue + FROM ehr_compliancedb.completiondates c + RIGHT JOIN ( + SELECT + c1.employeeid, + emp.email, + emp.Firstname + ' ' + emp.Lastname as Name, + emp.unit, + emp.category, + emp.location, + emp.majorudds, + emp.notes, + emp.isActive, + c1.requirementname, + c1.date, + c1.result, + c1.comment, + c1.trainer + FROM ehr_compliancedb.completiondates c1, ehr_compliancedb.employees emp + Where c1.employeeid = emp.employeeid + And c1.requirementname like 'Occupational Health - Measles Compliant - Initial' + And emp.endDate is null + ) emp + ON c.employeeid = emp.employeeid + And c.requirementname like 'Occupational Health - Measles Compliant' \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees.query.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees.query.xml new file mode 100644 index 000000000..4815c6bae --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees.query.xml @@ -0,0 +1,30 @@ + + + + + Employees + + + Host + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees/.qview.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees/.qview.xml new file mode 100644 index 000000000..d65d71743 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/employees/.qview.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements.query.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements.query.xml new file mode 100644 index 000000000..64d4ad8ff --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements.query.xml @@ -0,0 +1,23 @@ + + + + + Requirements + + + + + + + + + + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml new file mode 100644 index 000000000..17d0f4476 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/begin.html b/ONPRC_EHR_ComplianceDB/resources/views/begin.html index 199940a0c..620e2c538 100644 --- a/ONPRC_EHR_ComplianceDB/resources/views/begin.html +++ b/ONPRC_EHR_ComplianceDB/resources/views/begin.html @@ -22,7 +22,10 @@ name: 'Requirements Overdue/Due Soon', url: '<%=contextPath%>/query' + container + '/executeQuery.view?schemaName=ehr_compliancedb&query.queryName=ComplianceRecentTests&query.viewName=Overdue and Due Soon' },{ name: 'Occupational Health - Requirements Overdue/Due Soon', url: '<%=contextPath%>/query' + container + '/executeQuery.view?schemaName=ehr_compliancedb&query.queryName=ComplianceRecentTests&query.viewName=Occupational%20Health%20Compliance' - }] + },{ + name: 'Occupational Health - Measles Overdue/Due Soon', url: '<%=contextPath%>/query' + container + '/executeQuery.view?schemaName=ehr_compliancedb&query.queryName=Measles45DayAlert&query.DaysOverDue~neqornull=-1' + } + ] },{ header: 'Employee Information', items: [{ diff --git a/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html index 7c28640ab..c286dec8d 100644 --- a/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html +++ b/ONPRC_EHR_ComplianceDB/resources/views/printableComplianceReports.html @@ -1,5 +1,7 @@ \ No newline at end of file + + + diff --git a/onprc_ehr/resources/views/protocolDetails.html b/onprc_ehr/resources/views/protocolDetails.html index 6feaacb92..e4b38b9a7 100644 --- a/onprc_ehr/resources/views/protocolDetails.html +++ b/onprc_ehr/resources/views/protocolDetails.html @@ -33,6 +33,10 @@ tag: 'div', style: 'padding-bottom: 10px;', id: 'housingSummary_' + webpart.wrapperDivId + },{ + tag: 'div', + style: 'padding-bottom: 10px;', + id: 'housingSummarySpecie_' + webpart.wrapperDivId }]; var el = Ext4.get(webpart.wrapperDivId); @@ -124,6 +128,15 @@ failure: LDK.Utils.getErrorCallback() }).render('housingSummary_' + webpart.wrapperDivId); + LDK.Utils.getReadOnlyQWP({ + title: 'Housing Summary By Specie', + schemaName: 'study', + queryName: 'protocolHousingSummary_Species', + columns: 'id/demographics/species,totalAnimals', + filters: [LABKEY.Filter.create('protocol', protocol, LABKEY.Filter.Types.EQUAL)], + failure: LDK.Utils.getErrorCallback() + }).render('housingSummarySpecie_' + webpart.wrapperDivId); + LDK.Utils.getReadOnlyQWP({ title: 'Projects Under This Protocol', schemaName: 'ehr', diff --git a/onprc_ehr/resources/views/vetReview.html b/onprc_ehr/resources/views/vetReview.html index f70108950..536beebfe 100644 --- a/onprc_ehr/resources/views/vetReview.html +++ b/onprc_ehr/resources/views/vetReview.html @@ -25,7 +25,7 @@ 'Most of these notes will pertain to open cases, but this is not necessarily the case.

    ' + 'Each animal is assigned to a vet, using a series of rules. Vets can be assigned to either an IACUC protocol, an area, or a room. ' + 'To determine the assigned vet for each animal, the vet is preferentially selected based on IACUC assignment, then by room, and finally by area. ' + - '

  • Click here to view a list of vets assigned to living animals
  • ' + + '
  • Click here to view a list of vets assigned to living animals
  • ' + '
  • Click here to view the rules governing vet assignment
  • ' + '
  • Click here to view issues with vet assignmenta
  • ', @@ -61,7 +61,7 @@ queryConfig: { schemaName: 'study', queryName: 'demographics', - viewName: 'Vet Review', + viewName: 'Vet Review', filterArray: filterArray, scope: this, success: function(dr){ diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js index 875c965a9..f25c595dd 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/ResearchProcedures.js @@ -24,6 +24,11 @@ EHR.model.DataModelManager.registerMetadata('ResearchProcedures', { defaultValue: 'Procedure', hidden: true }, + + //Added: 6-21-2019 R.blasa hide Special Instructions + instructions: { + hidden: true + }, title: { hidden: true }, @@ -38,7 +43,7 @@ EHR.model.DataModelManager.registerMetadata('ResearchProcedures', { procedureid: { lookup: { filterArray: [ - LABKEY.Filter.create('category', 'Surgery', LABKEY.Filter.Types.NEQ), + LABKEY.Filter.create('category', 'Research;Procedure', LABKEY.Filter.Types.EQUALS_ONE_OF), //Modified: 7-23-2019 R.Blasa LABKEY.Filter.create('active', true, LABKEY.Filter.Types.EQUAL) ] } diff --git a/onprc_ehr/resources/web/onprc_ehr/onprcReports.js b/onprc_ehr/resources/web/onprc_ehr/onprcReports.js index ab1a6a16e..d60b3f372 100644 --- a/onprc_ehr/resources/web/onprc_ehr/onprcReports.js +++ b/onprc_ehr/resources/web/onprc_ehr/onprcReports.js @@ -152,6 +152,63 @@ EHR.reports.iStat = function(panel, tab){ }); } +//Added: 6-27-2019 R.Blasa +EHR.reports.TBTest = function(panel, tab){ + var filterArray = panel.getFilterArray(tab); + var title = panel.getTitleSuffix(); + + var target = tab.add({tag: 'span', style: 'padding-bottom: 20px'}); + tab.doLayout(); + + var config = panel.getQWPConfig({ + schemaName: 'study', + queryName: 'TBTestEnounters', + title: "TB Test Dates " + title, + titleField: 'Id', + filters: filterArray.nonRemovable, + removeableFilters: filterArray.removable, + sort: '-date' + }); + + tab.add({ + xtype: 'ldk-querypanel', + style: 'margin-bottom:20px;', + queryConfig: config + }); + + var miscConfig = panel.getQWPConfig({ + schemaName: 'study', + queryName: 'TBObservationsReport', + title: 'TB TST Scores' + title, + titleField: 'Id', + sort: '-date', + filters: filterArray.nonRemovable, + removeableFilters: filterArray.removable + }); + + tab.add({ + xtype: 'ldk-querypanel', + style: 'margin-bottom:20px;', + queryConfig: miscConfig + }); + + var resultsConfig = panel.getQWPConfig({ + schemaName: 'study', + queryName: 'TBTestSerologyLabResults', + title: 'TB Serology Results' + title, + titleField: 'Id', + sort: '-date', + filters: filterArray.nonRemovable, + removeableFilters: filterArray.removable + + }); + + tab.add({ + xtype: 'ldk-querypanel', + style: 'margin-bottom:20px;', + queryConfig: resultsConfig + }); +} EHR.reports.clinMedicationSchedule = function(panel, tab){ @@ -1054,7 +1111,7 @@ EHR.reports.kinshipSummary = function(panel, tab){ var dr = LABKEY.DataRegions[qwp.dataRegionName]; if (dr){ dr.addFilter(LABKEY.Filter.create('Id2', p.subjectList.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)); - dr.refresh(); + // dr.refresh(); Modidifed: 5-23-2019 R.Blasa Prevent from refreshing grid reports. } } } diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/ArrivalDataEntryPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/ArrivalDataEntryPanel.js new file mode 100644 index 000000000..b014c8897 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/panel/ArrivalDataEntryPanel.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014-2015 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +//Created: 8-6-2019 R.Blasa +Ext4.define('ONPRC_EHR.panel.ArrivalDataEntryPanel', { + extend: 'EHR.panel.TaskDataEntryPanel', + alias: 'widget.onprc-arrivaldataentrypanel', + + onStoreCollectionCommitComplete: function(sc, extraContext){ + if (Ext4.Msg.isVisible()) + Ext4.Msg.hide(); + + //Modified 6-5-2015 Blasa Note: provided a process to evaluate contents of store + // var store = sc.getClientStoreByName('housing'); + var store = sc.getClientStoreByName('arrival'); + LDK.Assert.assertNotEmpty('Unable to find housing store in HousingDataEntryPanel', store); + + if (extraContext && extraContext.successURL && store.getCount() > 0){ + Ext4.Msg.confirm('Success', 'Do you want to view the room layout now? This will allow you to verify and/or change dividers', function(val){ + window.onbeforeunload = Ext4.emptyFn; + if (val == 'yes'){ + + var rooms = []; + store.each(function(r){ + if (r.get('initialRoom') && rooms.indexOf(r.get('initialRoom')) == -1){ + rooms.push(r.get('initialRoom')); + } + }, this); + + window.location = LABKEY.ActionURL.buildURL('onprc_ehr', 'printRoom', null, {rooms: rooms}); + } + else { + window.location = extraContext.successURL; + } + }, this); + + return; + } + + this.callParent(arguments); + } +}); \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRController.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRController.java index 9c6fa9a41..068609367 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRController.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRController.java @@ -91,6 +91,8 @@ public ApiResponse execute(Object form, BindException errors) //Added 6-5-2016 Blasa resultProperties.put("sla", getSection("/ONPRC/SLA")); + //Added by kollil 5/7/2019 + resultProperties.put("reservation", getSection("/ONPRC/Room Reservations")); //for now, EHR is hard coded List ehr = new ArrayList<>(); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 974244859..d2fcf0002 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -53,14 +53,12 @@ import org.labkey.onprc_ehr.buttons.AssignmentReleaseConditionButton; import org.labkey.onprc_ehr.buttons.BulkEditRequestsButton; import org.labkey.onprc_ehr.buttons.ChangeProjectedReleaseDateButton; -import org.labkey.onprc_ehr.buttons.CreateNecropsyRequestButton; import org.labkey.onprc_ehr.buttons.CreateProjectButton; import org.labkey.onprc_ehr.buttons.HousingTransferButton; import org.labkey.onprc_ehr.buttons.ManageFlagsButton; import org.labkey.onprc_ehr.buttons.ProtocolEditButton; import org.labkey.onprc_ehr.buttons.VetReviewButton; import org.labkey.onprc_ehr.buttons.VetReviewRecordButton; -import org.labkey.onprc_ehr.buttons.CreateTaskFromRecordButtons; import org.labkey.onprc_ehr.dataentry.*; import org.labkey.onprc_ehr.demographics.ActiveAnimalGroupsDemographicsProvider; import org.labkey.onprc_ehr.demographics.ActiveCasesDemographicsProvider; @@ -73,7 +71,6 @@ import org.labkey.onprc_ehr.demographics.PregnancyConfirmDemographicsProvider; import org.labkey.onprc_ehr.demographics.SourceDemographicsProvider; import org.labkey.onprc_ehr.demographics.TBDemographicsProvider; -import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsEndDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalRecordFlagDataSource; @@ -177,6 +174,12 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext) //Added 8-7-2018 R.Blasa ns.registerNotification(new BirthHousingMismatchNotification(this)); + //Added 3-6-2019 Blasa + ns.registerNotification(new ProjectAlertsNotification(this)); + + //Added 6-4-2019 Additional Scheduled for 55pm + ns.registerNotification(new TreatmentAlertsPostOpsNotificationThird(this)); + ns.registerNotification(new RequestAdminNotification(this)); ns.registerNotification(new ColonyAlertsLiteNotification(this)); ns.registerNotification(new ColonyAlertsNotification(this)); @@ -248,8 +251,6 @@ private void registerEHRResources() //Added: 7-18-2018 R.Blasa EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageRecordWindow.js"), this); - - EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single Housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=demographicsPaired&query.viewName=Single Housed"), "Commonly Used Queries"); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "Find Animals Housed In A Given Room/Cage At A Specific Time", this, DetailsURL.fromString("/ehr/housingOverlaps.view?groupById=1"), "Commonly Used Queries"); @@ -290,18 +291,17 @@ private void registerEHRResources() //Added 5-16-2018 R.Blasa EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Date of Last Physical Exam by ID(s)", this, DetailsURL.fromString("/onprc_ehr/PE_ExamHistoryReportbyID.view"), "Routine Clinical Tasks"); - //Modified: 1-17-2019 R.Blasa + //Added 5-11-2015 New report for Lois Colgin try { - EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Pathology Laboratory Summary Report", this, new URLHelper("http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render") + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Laboratory Test Summary", this, new URLHelper("http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fPrimeLaboratory+Report&rs:Command=Render") { // SSRS is picky about the URI-encoding of the query parameters @Override //Modified: 1-17-2019 R.Blasa public String toString() { - return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render"; - + return "http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fPrimeLaboratory+Report&rs:Command=Render"; } }, "Clinical Pathology"); } @@ -310,17 +310,16 @@ public String toString() throw new UnexpectedException(e); } - //Modified 1-7-2019 R.Blasa + //Modified 9-9-2019 R.Blasa Show Full Exposure report instead of Basic Expsoure try { - EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Basic Exposure Report", this, new URLHelper("http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fBasicExposureMain&rs:Command=Render") + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Exposure Report", this, new URLHelper("http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fBasicExposureMain&rs:Command=Render") { // SSRS is picky about the URI-encoding of the query parameters @Override - //Modified: 1-17-2019 R.Blasa public String toString() { - return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fBasicExposureMain&rs:Command=Render"; + return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fDemographicsReportMain&rs:Command=Render"; } }, "Exposure Report"); } @@ -378,7 +377,6 @@ public String toString() EHRService.get().registerActionOverride("cageDetails", this, "views/cageDetails.html"); EHRService.get().registerActionOverride("animalSearch", this, "views/animalSearch.html"); EHRService.get().registerActionOverride("animalHistory", this, "views/animalHistory.html"); - EHRService.get().registerActionOverride("serviceRequests", this, "views/serviceRequests.html"); //Added: 10-2-2017 R.Blasa displays onperc version of enterData.view EHRService.get().registerActionOverride("enterData", this, "views/enterData.html"); @@ -401,7 +399,6 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SingleSurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyFormType.class, this)); - EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyRequestForm.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(BiopsyFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PathologyTissuesFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ClinicalReportFormType.class, this)); @@ -433,6 +430,8 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(DrugRequestBulkEditFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(LabworkRequestBulkEditFormType.class, this)); + //Added: 5/23/2019 Kollil +// EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PMICRequestFormType.class, this)); // Added: 11-21-2017 R.Blasa EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ProcedureRequestBulkEditFormType.class, this)); @@ -481,9 +480,6 @@ public String toString() //Created: 4-7-2015-10-2017 R.Blasa EHRService.get().registerDemographicsProvider(new ActiveTreatmentsXDemographicsProvider(this)); - //Created: 12-18-2018 R.Blasa - EHRService.get().registerDemographicsProvider(new LastHousingDemographicsProvider(this)); - //buttons EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "my_tasks"); EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "tasks"); @@ -518,8 +514,8 @@ public String toString() EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); - //Added: 1-18-2019 R.Blasa - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); + //Added: 7-29-2017 R.Blasa + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this), "study", "blood"); @@ -560,11 +556,6 @@ public String toString() EHRService.get().registerHistoryDataSource(new org.labkey.api.ehr.history.DefaultAnimalRecordFlagDataSource(this)); EHRService.get().registerHistoryDataSource(new ONPRCClinicalRemarksDataSource(this)); - EHRService.get().registerMoreActionsButton(new CreateNecropsyRequestButton(this), "study", "encounters"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "encounters"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "tissue_samples"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "organ_weights"); - EHRService.get().registerOptionalClinicalHistoryResources(this); EHRService.get().registerLabworkType(new ONPRCUrinalysisLabworkType(this)); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java index 79841a3ba..ed0012885 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java @@ -22,6 +22,7 @@ import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.ehr.dataentry.WeightFormSection; import org.labkey.api.module.Module; +import org.labkey.api.view.template.ClientDependency; import java.util.ArrayList; import java.util.Arrays; @@ -49,9 +50,12 @@ public ArrivalFormType(DataEntryFormContext ctx, Module owner) new WeightFormSection() )); - //setJavascriptClass("ONPRC_EHR.panel.NewAnimalDataEntryPanel"); - //addClientDependency(ClientDependency.fromFilePath("onprc_ehr/panel/NewAnimalDataEntryPanel.js")); +// Added: 8-6-2019 R.Blasa + addClientDependency(ClientDependency.fromPath("onprc_ehr/panel/ArrivalDataEntryPanel.js")); + setJavascriptClass("ONPRC_EHR.panel.ArrivalDataEntryPanel"); + + } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index 17e5cd8f4..4c59a8b65 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -341,13 +341,13 @@ protected void eventsInLast5Days(Container c, User u, StringBuilder msg) protected void roomsWithMixedViralStatus(final Container c, User u, final StringBuilder msg) { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("distinctStatuses"), 1 , CompareType.GT); - filter.addCondition(FieldKey.fromString("room/housingCondition/value"), "ABSL2+;ABSL3", CompareType.CONTAINS_NONE_OF); + filter.addCondition(FieldKey.fromString("room/housingCondition/value"), "ABSL2+;Sequester/Containment;ABSL3", CompareType.CONTAINS_NONE_OF); TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("housingMixedViralStatus"), filter, new Sort("area,room")); long count = ts.getRowCount(); if (count > 0) { - msg.append("WARNING: The following " + count + " rooms have animals with mixed viral statuses, excluding ABSL2+ and ABSL3 rooms:

    \n"); + msg.append("WARNING: The following " + count + " rooms have animals with mixed viral statuses, excluding ABSL2+,Sequester/Containment, and ABSL3 rooms:

    \n"); msg.append("Click here to view this list

    \n"); msg.append("\n"); @@ -400,6 +400,10 @@ protected void livingAnimalsWithoutWeight(final Container c, User u, final Strin { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("calculated_status"), "Alive"); filter.addCondition(FieldKey.fromString("Id/MostRecentWeight/MostRecentWeightDate"), null, CompareType.ISBLANK); + //Added by Kolli1, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates + //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG+;RABBIT", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG", CompareType.NEQ); + Sort sort = new Sort(getStudy(c).getSubjectColumnName()); TableInfo ti = getStudySchema(c, u).getTable("Demographics"); @@ -450,6 +454,10 @@ protected void deadAnimalsWithActiveHousing(final Container c, User u, final Str Sort sort = new Sort(getStudy(c).getSubjectColumnName()); SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Id/Dataset/Demographics/calculated_status"), "Alive", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("enddate"), null, CompareType.ISBLANK); + //Added by Kolli1, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates + //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG+;RABBIT", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG", CompareType.NEQ); + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("Housing"), filter, sort); long count = ts.getRowCount(); if (count > 0) @@ -475,6 +483,10 @@ protected void livingAnimalsWithoutHousing(final Container c, User u, final Stri Sort sort = new Sort(getStudy(c).getSubjectColumnName()); SimpleFilter filter = new SimpleFilter(FieldKey.fromString("calculated_status"), "Alive"); filter.addCondition(FieldKey.fromString("Id/curLocation/room/room"), null, CompareType.ISBLANK); + //Added by Kolli1, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates + //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG+;RABBIT", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG", CompareType.NEQ); + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("Demographics"), filter, sort); long count = ts.getRowCount(); if (count > 0) @@ -1842,6 +1854,9 @@ else if (count > 65) protected void infantsNotWithMother(final Container c, User u, final StringBuilder msg) { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Id/age/ageInDays"), 180, CompareType.LTE); + //Added by Kolli1, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates + //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG+;RABBIT", CompareType.CONTAINS_NONE_OF); + filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG", CompareType.NEQ); filter.addCondition(FieldKey.fromString("Id/demographics/calculated_status"), "Alive", CompareType.EQUAL); filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 191", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("withMother"), 0, CompareType.EQUAL); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ProjectAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ProjectAlertsNotification.java new file mode 100644 index 000000000..cf8b22a54 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ProjectAlertsNotification.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.notification; + +import org.jetbrains.annotations.Nullable; +import org.labkey.api.data.Container; +import org.labkey.api.ehr.notification.AbstractEHRNotification; +import org.labkey.api.module.Module; +import org.labkey.api.security.User; +import org.labkey.api.util.DateUtil; + +import java.util.Date; + +//Added 3-6-2019 R.Blasa + +public class ProjectAlertsNotification extends AbstractEHRNotification +{ + public ProjectAlertsNotification(Module owner) + { + super(owner); + } + + @Override + public String getName() + { + return "Center Project Notification"; + } + + @Override + public String getEmailSubject(Container c) + { + return "Project Alerts Notification: " + DateUtil.formatDateTime(c); + } + + @Override + public String getCronString() + { + return null; + } + + @Override + public String getScheduleDescription() + { + return "Sent immediately when a Center Project record is created"; + } + + @Override + public String getDescription() + { + return "The report sends an alert whenever a new Center Project record is created."; + } + + @Override + @Nullable + public String getMessageBodyHTML(Container c, User u) + { + //this is used as a placeholder so we can use it to track the list of subscribed users + return null ; + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java index abfff83ae..665149f2b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java @@ -26,12 +26,12 @@ import org.labkey.api.data.Sort; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; -import org.labkey.api.ehr.notification.AbstractEHRNotification; import org.labkey.api.module.Module; import org.labkey.api.query.FieldKey; import org.labkey.api.query.QueryService; import org.labkey.api.security.User; import org.labkey.api.util.PageFlowUtil; +import org.labkey.api.ehr.notification.AbstractEHRNotification; import java.sql.ResultSet; import java.sql.SQLException; @@ -60,7 +60,7 @@ public String getName() @Override public String getDescription() { - return "This runs every day at 9AM, 12PM, 1PM, 2PM, 3PM if there are treatments scheduled that have not yet been marked complete"; + return "This runs every day at 9AM,1PM,3PM if there are treatments scheduled that have not yet been marked complete"; } @Override @@ -70,12 +70,12 @@ public String getEmailSubject(Container c) } @Override - public String getCronString() {return "0 0 9,12,13,14,15 * * ?";} + public String getCronString() {return "0 0 9,13,15 * * ?";} @Override public String getScheduleDescription() { - return "daily at 9AM,12PM,1PM,2PM,3PM"; + return "daily at 9AM,1PM,3PM"; } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java new file mode 100644 index 000000000..88bd2cae4 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.notification; + +import org.apache.commons.lang3.time.DateUtils; +import org.labkey.api.data.ColumnInfo; +import org.labkey.api.data.CompareType; +import org.labkey.api.data.Container; +import org.labkey.api.data.Results; +import org.labkey.api.data.ResultsImpl; +import org.labkey.api.data.Selector; +import org.labkey.api.data.SimpleFilter; +import org.labkey.api.data.Sort; +import org.labkey.api.data.TableInfo; +import org.labkey.api.data.TableSelector; +import org.labkey.api.ehr.notification.AbstractEHRNotification; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; +import org.labkey.api.query.QueryService; +import org.labkey.api.security.User; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +//Added 6-4-2019 Blasa Post Op Meds 5Pm Schedule Only +public class TreatmentAlertsPostOpsNotificationThird extends AbstractEHRNotification +{ + public TreatmentAlertsPostOpsNotificationThird(Module owner) + { + super(owner); + } + + public String getName() + { + return "Treatment PostOpsMed Third Alert"; + } + + public String getDescription() + { + return "This runs every evening at 5:00PM if there are treatments scheduled that have not yet been marked complete"; + } + + public String getEmailSubject(Container c) + { + return "Daily Treatment PostOpsMed Alerts: " + getDateTimeFormat(c).format(new Date()); + } + + @Override //Modified 7/29/2015 Blasa + public String getCronString() { return "0 0 17 * * ?";} + + public String getScheduleDescription() + { + return "Evenings at 5:00 PM"; + } + + @Override + public String getMessageBodyHTML(Container c, User u) + { + StringBuilder msg = new StringBuilder(); + + //Find today's date + Date now = new Date(); + msg.append("This email contains any treatments not marked as completed. It was run on: " + getDateFormat(c).format(now) + " at " + _timeFormat.format(now) + ".

    "); + + + processPostOpsTreatments(c, u, msg, new Date()); + + return msg.toString(); + } + + + + // Added 7-21-2015 Blasa Address Notifications for only Post Ops Meds + private void processPostOpsTreatments(Container c, User u, final StringBuilder msg, final Date maxDate) + { + Date curDate = new Date(); + Date roundedMax = new Date(); + roundedMax.setTime(maxDate.getTime()); + roundedMax = DateUtils.truncate(roundedMax, Calendar.DATE); + + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("treatmentSchedulePostOps"); + + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("date"), roundedMax, CompareType.DATE_EQUAL); + filter.addCondition(FieldKey.fromString("date"), maxDate, CompareType.LTE); + filter.addCondition(FieldKey.fromString("Id/DataSet/Demographics/calculated_status"), "Alive"); + + + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("Id")); + columns.add(FieldKey.fromString("Id/curLocation/area")); + columns.add(FieldKey.fromString("Id/curLocation/room")); + columns.add(FieldKey.fromString("Id/curLoation/cage")); + columns.add(FieldKey.fromString("projectStatus")); + columns.add(FieldKey.fromString("treatmentStatus")); + columns.add(FieldKey.fromString("treatmentStatus/Label")); + columns.add(FieldKey.fromString("code")); + columns.add(FieldKey.fromString("code/meaning")); + + Map params = new HashMap<>(); + params.put("StartDate", roundedMax); + params.put("NumDays", 1); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts = new TableSelector(ti, colMap.values(), filter, new Sort("Id/curLocation/area,Id/curLocation/room")); + ts.setNamedParameters(params); + + String url = getExecuteQueryUrl(c, "study", "treatmentSchedulePostOps", null) + "&" + filter.toQueryString("query") + getParameterUrlString(c, params); + long total = ts.getRowCount(); + if (total == 0) + { + msg.append("There are no treatments scheduled on " + getDateFormat(c).format(maxDate) + " on or before " + _timeFormat.format(maxDate) + ". Treatments could be added after this email was sent, so please click here to check online closer to the time.


    \n"); + } + else + { + final String completed = "completed"; + final String incomplete = "incomplete"; + final Map totals = new HashMap<>(); + totals.put(completed, 0); + totals.put(incomplete, 0); + + final Map totalByArea = new TreeMap<>(); + + ts.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet object) throws SQLException + { + Results rs = new ResultsImpl(object, colMap); + //Modified 7-2-2015 Blasa Comparing QC state to column values + if ("Completed".equals(rs.getString(FieldKey.fromString("treatmentStatus")))) + { + totals.put(completed, totals.get(completed) + 1); + } + else + { + totals.put(incomplete, totals.get(incomplete) + 1); + + String area = rs.getString(FieldKey.fromString("Id/curLocation/area")); + Integer areaVal = totalByArea.containsKey(area) ? totalByArea.get(area) : 0; + areaVal++; + + totalByArea.put(area, areaVal); + } + } + }); + + msg.append("Treatments:

    "); + msg.append("There are " + (totals.get(completed) + totals.get(incomplete)) + " scheduled treatments on or before " + _timeFormat.format(maxDate) + ". Click here to view them. Of these, " + totals.get(completed) + " have been marked completed.

    \n"); + + if (totals.get(incomplete) == 0) + { + msg.append("All treatments scheduled prior to " + _timeFormat.format(maxDate) + " have been marked complete as of " + getDateTimeFormat(c).format(curDate) + ".

    \n"); + } + else + { + msg.append("There are " + totals.get(incomplete) + " treatments that have not been marked complete:

    \n"); + msg.append("

    "); + + for (String area : totalByArea.keySet()) + { + msg.append("\n"); + } + + msg.append("
    " + area + ":" + totalByArea.get(area) + "

    \n"); + } + msg.append("


    \n"); + } + } +} \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java index d95ff8907..3e30b8c7e 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +/*promoting to uat for verification*/ package org.labkey.onprc_ehr.notification; import org.labkey.api.data.ColumnInfo; @@ -43,7 +45,7 @@ */ public class VetReviewNotification extends ColonyAlertsNotification { - public VetReviewNotification(Module owner) + public VetReviewNotification (Module owner) { super(owner); } @@ -83,7 +85,7 @@ public String getMessageBodyHTML(Container c, User u) { StringBuilder msg = new StringBuilder(); - remarksWithoutAssignedVet(c, u, msg); + /* remarksWithoutAssignedVet(c, u, msg);*/ vetRecordsUnderReview(c, u, msg); animalsWithoutAssignedVet(c, u, msg); @@ -97,22 +99,25 @@ public void vetRecordsUnderReview(Container c, User u, final StringBuilder msg) doRemarkQuery(c, u, msg, filter, "ALERT: The following animals that have remarks entered at least " + duration + " days ago, but have not yet been reviewed."); } - public void remarksWithoutAssignedVet(Container c, User u, final StringBuilder msg) - { + /*public void remarksWithoutAssignedVet(Container c, User u, final StringBuilder msg); + { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Id/assignedVet/assignedVet"), null, CompareType.ISBLANK); filter.addCondition(FieldKey.fromString("totalRemarksEnteredSinceReview"), 0, CompareType.GT); doRemarkQuery(c, u, msg, filter, "ALERT: The following animals that have remarks entered, but the animal is not currently assigned to a vet."); - } + }*/ public void doRemarkQuery(Container c, User u, final StringBuilder msg, SimpleFilter filter, String header) { - TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("demographics"); + //TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("demographics_AssignedVetNotification"); +// TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("demographics_VetAssignment_Notification"); + //Changed by Kollil on 6/19/2019. Created a new query to get the vet assignment info + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("demographics_Vet_Assignment_Alert"); final Map cols = QueryService.get().getColumns(ti, PageFlowUtil.set( FieldKey.fromString("Id"), FieldKey.fromString("calculated_status"), FieldKey.fromString("earliestRemarkSinceReview"), FieldKey.fromString("lastVetReview"), - FieldKey.fromString("Id/assignedVet/assignedVet") + FieldKey.fromString("assignedVet") )); TableSelector ts = new TableSelector(ti, cols.values(), filter, new Sort("Id")); @@ -127,7 +132,7 @@ public void exec(ResultSet object) throws SQLException rows.add("" + "" + rs.getString(FieldKey.fromString("Id")) + "" + - "" + (rs.getString(FieldKey.fromString("Id/assignedVet/assignedVet")) == null ? "NONE" : rs.getString(FieldKey.fromString("Id/assignedVet/assignedVet"))) + "" + + "" + (rs.getString(FieldKey.fromString("assignedVet")) == null ? "NONE" : rs.getString(FieldKey.fromString("assignedVet"))) + "" + "" + getDateFormat(c).format(rs.getDate(FieldKey.fromString("earliestRemarkSinceReview"))) + "" + "" + (rs.getDate(FieldKey.fromString("lastVetReview")) == null ? "Never" : getDateFormat(c).format(rs.getDate(FieldKey.fromString("lastVetReview")))) + "" + "" + rs.getString(FieldKey.fromString("calculated_status")) + "" + @@ -152,7 +157,10 @@ protected void animalsWithoutAssignedVet(final Container c, User u, final String { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("calculated_status"), "Alive"); filter.addCondition(FieldKey.fromString("Id/assignedVet/assignedVet"), null, CompareType.ISBLANK); - TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("demographics"), filter, null); + //TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("demographics_AssignedVetNotification"), filter, null); +// TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("demographics_VetAssignment_Notification"), filter, null); + //Changed by Kollil on 6/19/2019. Created a new query to get the vet assignment info + TableSelector ts = new TableSelector(getStudySchema(c, u).getTable("demographics_Vet_Assignment_Alert"), filter, null); long count = ts.getRowCount(); if (count > 0) { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java index 6f1825303..3b99c0a67 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java @@ -16,6 +16,7 @@ package org.labkey.onprc_ehr.query; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; import org.apache.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.labkey.api.collections.CaseInsensitiveHashMap; @@ -69,6 +70,7 @@ import org.labkey.onprc_ehr.notification.CullListNotification; import org.labkey.onprc_ehr.notification.MensesTMBNotification; import org.labkey.onprc_ehr.notification.ProtocolAlertsNotification; +import org.labkey.onprc_ehr.notification.ProjectAlertsNotification; import javax.mail.Address; import javax.mail.Message; @@ -1218,8 +1220,8 @@ public void doBirthTriggers(String id, Date date, String dam, Date Arrival_Date, } // Added: 10-27-2017 R.Blasa Create an SPR4 entries for Rhesus macaques - - if ("Live Birth".equalsIgnoreCase(birthCondition) && "RHESUS MACAQUE".equalsIgnoreCase(species) ) +// Modified: 6-19-2019 R.Blasa to Create SP4 when Rhesus and no Dam assigned to Infant + if ("Live Birth".equalsIgnoreCase(birthCondition) && "RHESUS MACAQUE".equalsIgnoreCase(species) && dam == null ) { @@ -1274,6 +1276,41 @@ else if (flagList.size() > 1) { _log.error("dam has more than 1 active SPF flag: " + dam); } + else if (flagList.size() == 0) + { + // Added: 6-19-2019 R.Blasa Create new flag if dam is not assigned to SPRF and Rhesus Macaque + if ("Live Birth".equalsIgnoreCase(birthCondition) && "RHESUS MACAQUE".equalsIgnoreCase(species) ) + + { + + String SPFFlag = getFlag("SPF", "SPF 4", null, true); + + TableInfo flagsSP4 = getTableInfo("study", "flags"); + SimpleFilter flagFilter2 = new SimpleFilter(FieldKey.fromString("Id"), id); + + //Note: Validate if SPF 4 is active + flagFilter2.addCondition(FieldKey.fromString("flag/value"), "SPF 4"); + flagFilter2.addClause(new SimpleFilter.OrClause( + new CompareType.CompareClause(FieldKey.fromString("enddate"), CompareType.DATE_GTE, date), + new CompareType.CompareClause(FieldKey.fromString("enddate"), CompareType.ISBLANK, null) + )); + + + TableSelector existingSP4 = new TableSelector(flagsSP4, Collections.singleton("flag"), flagFilter2, null); + if (existingSP4.exists()) + { + _log.info("SP4 Flag active record exist for this monkey id: " + id + "Value") ; + } + else + { + _log.info("adding SP4 Animal : " + id + "Value"); + + EHRService.get().ensureFlagActive(getUser(), getContainer(), SPFFlag, date, enddate, null, Collections.singletonList(id), false); + + } + } + } + //also breeding groups TableInfo animalGroups = getTableInfo("study", "animal_group_members"); @@ -2219,6 +2256,98 @@ public void exec(ResultSet rs) throws SQLException } + + //Added 3-6-2019 Blasa + public void sendProjectNotifications(Integer projectid) + { + + if (!NotificationService.get().isServiceEnabled()) + { + _log.info("notification service is not enabled, will not send Project notification."); + return; + } + + String subject = "Center Project Notification: "; + + Set recipients = NotificationService.get().getRecipients(new ProjectAlertsNotification(ModuleLoader.getInstance().getModule(ONPRC_EHRModule.class)), getContainer()); + + if (recipients.size() == 0) + { + _log.warn("No recipients, Center Project notification"); + return; + } + final StringBuilder html = new StringBuilder(); + +// Added: 4-3-2019 R.Blasa + Date roundedMax = new Date(); + roundedMax = DateUtils.truncate(roundedMax, Calendar.DATE); + + TableInfo ti = getTableInfo("ehr", "project"); + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("project"), projectid); + filter.addCondition(FieldKey.fromString("enddateCoalesced"), roundedMax, CompareType.GTE); + + Sort sort = new Sort("name"); + + List names= new ArrayList<>(); + FieldKey protocolFieldKey = FieldKey.fromString("protocol/external_id"); + names.add(protocolFieldKey); + names.add(FieldKey.fromString("name")); + names.add(FieldKey.fromString("investigatorId")); + names.add(FieldKey.fromString("startdate")); + names.add(FieldKey.fromString("project")); + + final Map colKeys = QueryService.get().getColumns(ti, names); + final ColumnInfo protocolColumn = colKeys.get(protocolFieldKey); + TableSelector ts = new TableSelector(ti, colKeys.values(), filter, sort); + + if (ts.getRowCount() == 0) + { + html.append("There are no Center Projects to display"); + _log.info("Success Section Part 1X"); + return; + } + else + { + //Create header information on the report + + html.append(""); + html.append("\n"); + ts.forEach(new Selector.ForEachBlock() + { + + @Override + public void exec(ResultSet rs) throws SQLException + { + + TableInfo ti2 = getTableInfo("onprc_ehr", "investigators"); + SimpleFilter filter2 = new SimpleFilter(FieldKey.fromString("rowid"), rs.getString("investigatorId")); + filter2.addCondition(FieldKey.fromString("datedisabled"), true, CompareType.ISBLANK); + + TableSelector ts2 = new TableSelector(ti2, PageFlowUtil.set("lastname"), filter2, null); + List ret2 = ts2.getArrayList(String.class); + if (ret2 != null && !ret2.isEmpty()) + { + for (String Investname : ret2) + { + html.append("\n"); + break; + + } + } + } + + } + + ); + + } + + html.append("
    Center ProjectProject IDIacuc Protocol Investigator Center Project Start Date
    " + ( rs.getString("name")) + "" + ( rs.getString("project")) + " " + ( rs.getString(protocolColumn.getAlias())) + " " + Investname + " " + rs.getString("startdate") + "
    \n"); + + sendMessage(subject, html.toString(), recipients); + + } + //Added 9-2-2015 Blasa private void sendMessage(String subject, String bodyHtml, Collection recipients) { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java index bf1f09113..23d09c6c4 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java @@ -267,6 +267,8 @@ private void addCalculatedCols(AbstractTableInfo ds, String dateColName) appendGroupsAtTimeCol(ehrSchema, ds, dateColName); appendProblemsAtTimeCol(ehrSchema, ds, dateColName); appendFlagsAtTimeCol(ehrSchema, ds, dateColName); +// Added:7-16-2019 R.Blasa + appendFlagsAlertActiveCol(ehrSchema, ds); appendIsAssignedAtTimeCol(ehrSchema, ds, dateColName); } } @@ -2143,6 +2145,71 @@ public TableInfo getLookupTableInfo() ds.addColumn(col); } +// Added:7-19-2019 R.Blasa Show Alert Flag categories only +private void appendFlagsAlertActiveCol(final UserSchema ehrSchema, AbstractTableInfo ds) +{ + String name = "flagsAlertsActive"; + if (ds.getColumn(name) != null) + return; + + final ColumnInfo pkCol = getPkCol(ds); + if (pkCol == null) + return; + + if (ds.getColumn("Id") == null) + return; + + if (!hasTable(ds, "study", "flags", ehrSchema.getContainer())) + return; + + final String tableName = ds.getName(); + final String queryName = ds.getPublicName(); + final String schemaName = ds.getPublicSchemaName(); + final UserSchema targetSchema = ds.getUserSchema(); + final String ehrPath = ehrSchema.getContainer().getPath(); + + WrappedColumn col = new WrappedColumn(pkCol, name); + col.setLabel("Flags Alerts Active"); + col.setReadOnly(true); + col.setIsUnselectable(true); + col.setUserEditable(false); + col.setFk(new LookupForeignKey(){ + public TableInfo getLookupTableInfo() + { + String name = tableName + "_flagsAtTime"; + QueryDefinition qd = QueryService.get().createQueryDef(targetSchema.getUser(), targetSchema.getContainer(), targetSchema, name); + qd.setSql("SELECT\n" + + "sd." + pkCol.getSelectName() + ",\n" + + "group_concat(DISTINCT h.flag.value, chr(10)) as flagsAlertsActive\n" + + "FROM \"" + schemaName + "\".\"" + queryName + "\" sd\n" + + "JOIN \"" + ehrPath + "\".study.flags h\n" + + " ON (sd.id = h.id AND h.flag.category = 'Alert' AND (h.dateOnly <= CAST(NOW() AS DATE) AND ((CAST(NOW() AS DATE) <= h.enddateCoalesced) or h.enddate is null)) AND h.qcstate.publicdata = true)\n" + + "group by sd." + pkCol.getSelectName()); + qd.setIsTemporary(true); + + List errors = new ArrayList<>(); + TableInfo ti = qd.getTable(errors, true); + if (errors.size() > 0) + { + _log.error("Error creating lookup table for: " + schemaName + "." + queryName + " in container: " + targetSchema.getContainer().getPath()); + for (QueryException error : errors) + { + _log.error(error.getMessage(), error); + } + return null; + } + + ti.getColumn(pkCol.getName()).setHidden(true); + ti.getColumn(pkCol.getName()).setKeyField(true); + + ti.getColumn("flagsAlertsActive").setLabel("Flags Alerts Active"); + + return ti; + } + }); + + ds.addColumn(col); +} private void appendProblemsAtTimeCol(final UserSchema ehrSchema, AbstractTableInfo ds, final String dateColName) { diff --git a/sla/resources/queries/sla/PlandProtocols.sql b/sla/resources/queries/sla/PlandProtocols.sql index 5b81e0494..7e82c9194 100644 --- a/sla/resources/queries/sla/PlandProtocols.sql +++ b/sla/resources/queries/sla/PlandProtocols.sql @@ -1,5 +1,6 @@ SELECT a.project as ProjectID, +aa.species, a.account as Alias, y.grantNumber as OGAGrantNumber, a.protocol as ParentIACUC, @@ -11,7 +12,7 @@ i.FirstName, i.LastName, i.Division, p.external_id, -i.LastName + ': ' + a.name + '('+ p.external_id +')' + ' - ' + a.title as PIIacuc +i.LastName + ': ' + a.name + '('+ p.external_id +')' + ' - ' + a.title + ' (Species: ' + aa.species + ')' as PIIacuc FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.project a LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.ehr.protocol p ON p.protocol = a.protocol LEFT JOIN onprc_ehr.investigators i ON i.rowId = a.investigatorId diff --git a/sla/resources/web/sla/form/CreatePurchaseOrder.js b/sla/resources/web/sla/form/CreatePurchaseOrder.js index 170b2a71d..32faa2780 100644 --- a/sla/resources/web/sla/form/CreatePurchaseOrder.js +++ b/sla/resources/web/sla/form/CreatePurchaseOrder.js @@ -458,7 +458,8 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { } //added by Kolli - if (speciesRowData.room == 'NSI 0123D' || speciesRowData.room == 'NSI 0125D' ) + //Added the new room to the list: NSI 134 by Kolli on 4/19 + if (speciesRowData.room == 'NSI 0123D' || speciesRowData.room == 'NSI 0125D' || speciesRowData.room == 'NSI 0134') { isHazardsRequired = true; } @@ -467,7 +468,7 @@ Ext4.define('SLA.panel.PurchaseOrderRequest', { //if (isHazardsRequired && (purchaseData.listHazard == null || purchaseData.listHazard == '')) if (isHazardsRequired && (purchaseData.hazardslist == null || purchaseData.hazardslist == '')) { - this.showErrorMsg('You have selected Location(s): NSI 0123D or NSI 0125D. Please list the biological or chemical agents! '); + this.showErrorMsg('You have selected Location(s): NSI 0123D or NSI 0125D or NSI 134. Please list the biological or chemical agents! '); return; } diff --git a/sla/resources/web/sla/form/PurchaseOrderForm.js b/sla/resources/web/sla/form/PurchaseOrderForm.js index fc31b66ff..c144dc27a 100644 --- a/sla/resources/web/sla/form/PurchaseOrderForm.js +++ b/sla/resources/web/sla/form/PurchaseOrderForm.js @@ -170,7 +170,7 @@ Ext4.define('SLA.form.PurchaseForm', { name: 'hazardslist', value: this.initData['hazardslist'], disabled: this.isUpdate && !LABKEY.user.canUpdate, - fieldLabel: 'List Biological or Chemical agents (Required for NSI 0123D, NSI 0125D)', + fieldLabel: 'List Biological or Chemical agents (Required for NSI 0123D, NSI 0125D, NSI 0134)', labelWidth: this.FIELD_LABEL_WIDTH }); diff --git a/sla/resources/web/sla/form/PurchaseSpeciesGrid.js b/sla/resources/web/sla/form/PurchaseSpeciesGrid.js index 506d6580f..2d5e3eb04 100644 --- a/sla/resources/web/sla/form/PurchaseSpeciesGrid.js +++ b/sla/resources/web/sla/form/PurchaseSpeciesGrid.js @@ -303,7 +303,7 @@ Ext4.define('SLA.form.SpeciesGrid', { } }, { - hidden: !LABKEY.user.canUpdate, // fields in this form should only be seen by Editors + //hidden: !LABKEY.user.canUpdate, // fields in this form should only be seen by Editors dataIndex: 'sla_DOB', text: 'SLA DOB', width: 250, From 819007198c38ac1e91fdd40c58a8f419e71f8acf Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 16:44:03 -0700 Subject: [PATCH 07/49] Merge from onprc19.1 r.64748 --- .../queries/study/DrugsGiven72hours.sql | 55 ++++ .../queries/study/TBObservationArea.sql | 26 ++ .../study/TreatmentSchedulePostOps.sql | 260 ++++++++++++------ .../resources/views/SliderDefinition.html | 21 ++ .../resources/views/SliderDefinition.view.xml | 5 + .../web/onprc_ehr/DemographicsRecord.js | 5 + .../form/field/TB_TST_Scores_Type.js | 42 +++ .../model/sources/TB_TestObservation.js | 59 ++++ .../model/sources/TreatmentDrugsClinical.js | 22 ++ .../web/onprc_ehr/panel/RoomLayoutPanel.js | 36 ++- .../web/onprc_ehr/panel/SnapshotPanel.js | 89 ++++++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 23 +- .../dataentry/TBObservationFormSection.java | 40 +++ .../dataentry/TBTestObservationFormType.java | 67 +++++ .../dataentry/TreatmentsFormType.java | 9 + .../ActiveDrugsGivenDemographicsProvider.java | 65 +++++ .../notification/ObeseFlagNotification.java | 26 +- .../TreatmentAlertsPostOpsNotification.java | 104 ++++++- ...entAlertsPostOpsNotificationSecondary.java | 98 +++++++ ...eatmentAlertsPostOpsNotificationThird.java | 98 +++++++ 20 files changed, 1058 insertions(+), 92 deletions(-) create mode 100644 onprc_ehr/resources/queries/study/DrugsGiven72hours.sql create mode 100644 onprc_ehr/resources/queries/study/TBObservationArea.sql create mode 100644 onprc_ehr/resources/views/SliderDefinition.html create mode 100644 onprc_ehr/resources/views/SliderDefinition.view.xml create mode 100644 onprc_ehr/resources/web/onprc_ehr/form/field/TB_TST_Scores_Type.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/TB_TestObservation.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/TreatmentDrugsClinical.js create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBObservationFormSection.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveDrugsGivenDemographicsProvider.java diff --git a/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql b/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql new file mode 100644 index 000000000..f9877b019 --- /dev/null +++ b/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +-- Created: 10-4-2019 R.Blasa + +SELECT + p.id as Id, + p.date, + timestampadd('SQL_TSI_HOUR',72,p.date ) as enddate, + p.code.code as code, + p.code.meaning as meaning, + p.amountAndVolume, + p.route, + timestampdiff('SQL_TSI_HOUR',p.date, now() ) as ElapseHours, + p.remark, + p.category + +FROM study.drug p +WHERE p.qcstate.publicdata = true +and timestampdiff('SQL_TSI_HOUR',p.date, now() ) < 73 +and p.code = 'E-Y9723' +and p.route <> 'Spillage' + +UNION + +SELECT + s.id as Id, + s.date, + timestampadd('SQL_TSI_HOUR',72,s.date ) as enddate, + s.code.code as code, + s.code.meaning as meaning, + s.amountAndVolume, + s.route, + timestampdiff('SQL_TSI_HOUR',s.date, now() ) as ElapseHours, + s.remark, + s.category + +FROM study.treatment_order s +WHERE s.qcstate.publicdata = true +and timestampdiff('SQL_TSI_HOUR',s.date, now() ) < 73 +and s.code = 'E-Y9723' +and s.route <> 'Spillage' diff --git a/onprc_ehr/resources/queries/study/TBObservationArea.sql b/onprc_ehr/resources/queries/study/TBObservationArea.sql new file mode 100644 index 000000000..d11384424 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TBObservationArea.sql @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +SELECT + t.value, + t.label, + t.sort_order + + +FROM sla.Reference_Data t +where t.columnName = 'TBTestObserveArea' +And t.enddate is null + + diff --git a/onprc_ehr/resources/queries/study/TreatmentSchedulePostOps.sql b/onprc_ehr/resources/queries/study/TreatmentSchedulePostOps.sql index 91edad81a..1ef8ef9bf 100644 --- a/onprc_ehr/resources/queries/study/TreatmentSchedulePostOps.sql +++ b/onprc_ehr/resources/queries/study/TreatmentSchedulePostOps.sql @@ -1,94 +1,73 @@ /* * Copyright (c) 2015 LabKey Corporation - * * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -SELECT -h.id, -h.calculated_status, -s.*, -s.objectid as treatmentid, - ---Modified 7-2-2015 Blasa from d.qcstate to d.qcstate.label -(SELECT max(d.qcstate.label) as label FROM study.drug d WHERE s.objectid = d.treatmentid AND s.date = d.timeordered) as treatmentStatus + -- Modified by Kolli on 9/10/2019 +*/ +SELECT + h.id, + h.calculated_status, + --s.TreatmentStatus, + (SELECT max(d.qcstate.label) as label FROM study.drug d WHERE s.objectid = d.treatmentid and s.date = d.timeordered) as TreatmentStatus, + h.Id.curLocation.room as room, + h.Id.curLocation.cage as cage, + s.date, + s.startDate, + s.endDate, + s.dayselapsed, + s.category, + s.code, + s.code.meaning as medication, + s.volume, + s.vol_units, + s.concentration, + s.conc_units, + s.amountWithUnits, + s.amountAndVolume, + s.dosage, + s.dosage_units, + s.frequency, + s.route, + s.reason, + s.remark, + s.performedby FROM study.demographics h JOIN ( SELECT - s.*, - timestampadd('SQL_TSI_MINUTE', ((s.hours * 60) + s.minutes), s.origDate) as date, - CASE - WHEN (hours >= 6 AND hours < 20) THEN 'AM' - WHEN (hours < 6 OR hours >= 20) THEN 'PM' - ELSE 'Other' - END as timeOfDay, - - ((s.hours * 60) + s.minutes) as timeOffset - + s.animalid, s.TreatmentStatus, timestampadd('SQL_TSI_MINUTE', ((s.hours * 60) + s.minutes), s.origDate) as date, s.objectid, + s.startdate, s.enddate, s.dayselapsed, s.category, s.code, s.volume, s.vol_units, s.concentration, s.conc_units, + s.amountWithUnits, s.amountAndVolume, s.dosage, s.dosage_units, s.frequency, s.route, s.reason, s.remark, s.performedby FROM ( SELECT - t1.lsid, - t1.objectid, - t1.dataset, - t1.id as animalid, - - coalesce(tt.time, ft.hourofday, ((hour(t1.date) * 100) + minute(t1.date))) as time, - (coalesce(tt.time, ft.hourofday, (hour(t1.date) * 100)) / 100) as hours, - CASE - WHEN (tt.time IS NOT NULL OR ft.hourofday IS NOT NULL) THEN (((coalesce(tt.time, ft.hourofday) / 100.0) - floor(coalesce(tt.time, ft.hourofday) / 100)) * 100) - ELSE minute(t1.date) - END as minutes, - dr.date as origDate, - --ft.timedescription as timeOfDay, - CASE - WHEN (tt.time IS NULL) THEN 'Default' - ELSE 'Custom' - END as timeType, - - CASE - WHEN snomed.code IS NOT NULL THEN 'Post Op Meds' - ELSE t1.category - END as category, - --t1.category, - - t1.frequency.meaning as frequency, - t1.date as startDate, - timestampdiff('SQL_TSI_DAY', cast(t1.dateOnly as timestamp), dr.dateOnly) + 1 as daysElapsed, - t1.enddate, - --t1.duration, - t1.project, - t1.code, - - t1.volume, - t1.vol_units, - t1.concentration, - t1.conc_units, - t1.amount, - t1.amount_units, - t1.amountWithUnits, - t1.amountAndVolume, - t1.dosage, - t1.dosage_units, - t1.qualifier, - - t1.route, - t1.reason, - t1.performedby, - t1.remark, - --t1.description, - - t1.qcstate + t1.objectid, + t1.id as animalid, + (coalesce(tt.time, ft.hourofday, (hour(t1.date) * 100)) / 100) as hours, + + CASE + WHEN (tt.time IS NOT NULL OR ft.hourofday IS NOT NULL) THEN (((coalesce(tt.time, ft.hourofday) / 100.0) - floor(coalesce(tt.time, ft.hourofday) / 100)) * 100) + ELSE minute(t1.date) + END as minutes, + dr.date as origDate, + + CASE + WHEN snomed.code IS NOT NULL THEN 'Post Op Meds' + ELSE t1.category + END as category, + + t1.date as startDate, + timestampdiff('SQL_TSI_DAY', cast(t1.dateOnly as timestamp), dr.dateOnly) + 1 as daysElapsed, + t1.enddate, t1.code, t1.volume, t1.vol_units, t1.concentration, t1.conc_units, t1.amountWithUnits, + t1.amountAndVolume, t1.dosage, t1.dosage_units, t1.frequency.meaning + ' (' + t1.frequency.times + ')' as frequency, t1.route, + t1.reason, t1.performedby, t1.remark, t1.qcstate.label as TreatmentStatus FROM ehr_lookups.dateRange dr -JOIN study."Treatment Orders" t1 - --NOTE: should the enddate consider date/time? - ON (dr.dateOnly >= t1.dateOnly and dr.dateOnly <= t1.enddateCoalesced AND - --technically the first day of the treatment is day 1, not day 0 - mod(CAST(timestampdiff('SQL_TSI_DAY', CAST(t1.dateOnly as timestamp), dr.dateOnly) as integer), t1.frequency.intervalindays) = 0 - ) +Join study."Treatment Orders" t1 + ON (dr.dateOnly >= t1.dateOnly and dr.dateOnly <= t1.enddateCoalesced AND + mod(CAST(timestampdiff('SQL_TSI_DAY', CAST(t1.dateOnly as timestamp), dr.dateOnly) as integer), t1.frequency.intervalindays) = 0 + ) LEFT JOIN ehr.treatment_times tt ON (tt.treatmentid = t1.objectid) LEFT JOIN ehr_lookups.treatment_frequency_times ft ON (ft.frequency = t1.frequency.meaning AND tt.rowid IS NULL) @@ -104,13 +83,128 @@ INNER JOIN ( --NOTE: if we run this report on a future interval, we want to include those treatments WHERE t1.date is not null --NOTE: they have decided to include non-public data ---AND t1.qcstate.publicdata = true --and t1.dateOnly <= curdate() ) s ) s ON (s.animalid = h.id) - -WHERE h.calculated_status = 'Alive' - ---account for date/time in schedule -and s.date >= s.startDate and s.date <= s.enddate \ No newline at end of file + WHERE h.calculated_status = 'Alive' + --account for date/time in schedule + and s.date >= s.startDate and s.date <= s.enddate + + +-- /* +-- * Copyright (c) 2015 LabKey Corporation +-- * +-- * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 +-- */ +-- +-- SELECT +-- h.id, +-- h.calculated_status, +-- s.*, +-- s.objectid as treatmentid, +-- ---Modified 7-2-2015 Blasa from d.qcstate to d.qcstate.label +-- (SELECT max(d.qcstate.label) as label FROM study.drug d WHERE s.objectid = d.treatmentid AND s.date = d.timeordered) as treatmentStatus +-- +-- +-- FROM study.demographics h JOIN ( +-- +-- SELECT +-- s.*, +-- timestampadd('SQL_TSI_MINUTE', ((s.hours * 60) + s.minutes), s.origDate) as date, +-- CASE +-- WHEN (hours >= 6 AND hours < 20) THEN 'AM' +-- WHEN (hours < 6 OR hours >= 20) THEN 'PM' +-- ELSE 'Other' +-- END as timeOfDay, +-- +-- ((s.hours * 60) + s.minutes) as timeOffset +-- +-- FROM ( +-- +-- SELECT +-- t1.lsid, +-- t1.objectid, +-- t1.dataset, +-- t1.id as animalid, +-- +-- coalesce(tt.time, ft.hourofday, ((hour(t1.date) * 100) + minute(t1.date))) as time, +-- (coalesce(tt.time, ft.hourofday, (hour(t1.date) * 100)) / 100) as hours, +-- CASE +-- WHEN (tt.time IS NOT NULL OR ft.hourofday IS NOT NULL) THEN (((coalesce(tt.time, ft.hourofday) / 100.0) - floor(coalesce(tt.time, ft.hourofday) / 100)) * 100) +-- ELSE minute(t1.date) +-- END as minutes, +-- dr.date as origDate, +-- --ft.timedescription as timeOfDay, +-- CASE +-- WHEN (tt.time IS NULL) THEN 'Default' +-- ELSE 'Custom' +-- END as timeType, +-- +-- CASE +-- WHEN snomed.code IS NOT NULL THEN 'Post Op Meds' +-- ELSE t1.category +-- END as category, +-- --t1.category, +-- +-- t1.frequency.meaning as frequency, +-- t1.date as startDate, +-- timestampdiff('SQL_TSI_DAY', cast(t1.dateOnly as timestamp), dr.dateOnly) + 1 as daysElapsed, +-- t1.enddate, +-- --t1.duration, +-- t1.project, +-- t1.code, +-- +-- t1.volume, +-- t1.vol_units, +-- t1.concentration, +-- t1.conc_units, +-- t1.amount, +-- t1.amount_units, +-- t1.amountWithUnits, +-- t1.amountAndVolume, +-- t1.dosage, +-- t1.dosage_units, +-- t1.qualifier, +-- +-- t1.route, +-- t1.reason, +-- t1.performedby, +-- t1.remark, +-- --t1.description, +-- +-- t1.qcstate +-- +-- FROM ehr_lookups.dateRange dr +-- +-- JOIN study."Treatment Orders" t1 +-- --NOTE: should the enddate consider date/time? +-- ON (dr.dateOnly >= t1.dateOnly and dr.dateOnly <= t1.enddateCoalesced AND +-- --technically the first day of the treatment is day 1, not day 0 +-- mod(CAST(timestampdiff('SQL_TSI_DAY', CAST(t1.dateOnly as timestamp), dr.dateOnly) as integer), t1.frequency.intervalindays) = 0 +-- ) +-- +-- LEFT JOIN ehr.treatment_times tt ON (tt.treatmentid = t1.objectid) +-- LEFT JOIN ehr_lookups.treatment_frequency_times ft ON (ft.frequency = t1.frequency.meaning AND tt.rowid IS NULL) +-- +-- INNER JOIN ( +-- SELECT +-- sc.code +-- from ehr_lookups.snomed_subset_codes sc +-- WHERE sc.primaryCategory = 'Post Op Meds' +-- GROUP BY sc.code +-- ) snomed ON snomed.code = t1.code +-- +-- --NOTE: if we run this report on a future interval, we want to include those treatments +-- WHERE t1.date is not null +-- --NOTE: they have decided to include non-public data +-- --AND t1.qcstate.publicdata = true --and t1.dateOnly <= curdate() +-- +-- ) s +-- +-- ) s ON (s.animalid = h.id) +-- +-- WHERE h.calculated_status = 'Alive' +-- +-- --account for date/time in schedule +-- and s.date >= s.startDate and s.date <= s.enddate \ No newline at end of file diff --git a/onprc_ehr/resources/views/SliderDefinition.html b/onprc_ehr/resources/views/SliderDefinition.html new file mode 100644 index 000000000..454f6f0ed --- /dev/null +++ b/onprc_ehr/resources/views/SliderDefinition.html @@ -0,0 +1,21 @@ + diff --git a/onprc_ehr/resources/views/SliderDefinition.view.xml b/onprc_ehr/resources/views/SliderDefinition.view.xml new file mode 100644 index 000000000..17a6fb71a --- /dev/null +++ b/onprc_ehr/resources/views/SliderDefinition.view.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js b/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js index 069f3c1da..7ebf9bcb1 100644 --- a/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js +++ b/onprc_ehr/resources/web/onprc_ehr/DemographicsRecord.js @@ -73,6 +73,11 @@ EHR.DemographicsRecord = function(data){ return data['lastlocation']; }, + //Created: 10-4-2019 R.Blasa + getActiveDrugs: function(){ + return data['activeDrugs']; + }, + getCurrentLocation: function(){ if (data['activeHousing'] && data['activeHousing'].length){ var ret = data['activeHousing'][0].room; diff --git a/onprc_ehr/resources/web/onprc_ehr/form/field/TB_TST_Scores_Type.js b/onprc_ehr/resources/web/onprc_ehr/form/field/TB_TST_Scores_Type.js new file mode 100644 index 000000000..392c8057a --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/form/field/TB_TST_Scores_Type.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * Created: R.Blasa on 11/4/2016. + */ +Ext4.define('onprc_ehr.form.field.onprc_TB_TST_ObservationScores', { + extend: 'Ext.form.field.ComboBox', + alias: 'widget.onprc_TB_TST_ObservationScores', + + + nullCaption: '[Blank]', + expandToFitContent: true, + caseSensitive: false, + anyMatch: true, + typeAhead: true, + + initComponent: function(){ + Ext4.apply(this, { + displayField:'value', + valueField: 'value', + queryMode: 'local', + store: Ext4.create('LABKEY.ext4.data.Store', { + schemaName: 'sla', + queryName: 'Reference_Data', + columns: 'value', + sort: 'value', + filterArray: [ + LABKEY.Filter.create('enddate', null, LABKEY.Filter.Types.ISBLANK), + LABKEY.Filter.create('ColumnName', 'TBTestObserveScore', LABKEY.Filter.Types.EQUAL)], + autoLoad: true + }) + }); + + this.callParent(arguments); + + + + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/TB_TestObservation.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/TB_TestObservation.js new file mode 100644 index 000000000..28a64c120 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/TB_TestObservation.js @@ -0,0 +1,59 @@ + +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +EHR.model.DataModelManager.registerMetadata('TB_TestObservation', { + allQueries: { + + }, + byQuery: { + 'study.clinical_observations': { + category: { + xtype: 'combo', + fieldLabel: 'Category', + defaultValue: 'TB TST Score (72 hr)', + displayField: 'value', + valueField: 'value', + + store: { + type: 'labkey-store', + schemaName: 'sla', + queryName: 'Reference_Data', + filterArray: [LABKEY.Filter.create('enddate', null, LABKEY.Filter.Types.ISBLANK), + LABKEY.Filter.create('columnName', 'TBTestObserveCategory', LABKEY.Filter.Types.EQUAL)], + autoLoad: true, + sort: 'sort_order' + } + + }, + observation: { + allowBlank: false, + xtype: 'onprc_TB_TST_ObservationScores' , + defaultValue: 'Grade: 0', + columnConfig: { + width: 200 + } + }, + + code:{ hidden: true}, + + area: { + xtype: 'combo', + fieldLabel: 'Area', + defaultValue: 'Right Eyelid', + displayField: 'label', + valueField: 'value', + store: { + type: 'labkey-store', + schemaName: 'study', + queryName: 'TBObservationArea', + autoLoad: true, + sort: 'sort_order' + } + } + } + + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/TreatmentDrugsClinical.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/TreatmentDrugsClinical.js new file mode 100644 index 000000000..dbb0138f3 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/TreatmentDrugsClinical.js @@ -0,0 +1,22 @@ + +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +//Created: 10-7-2019 R.Blasa + + EHR.model.DataModelManager.registerMetadata('TreatmentDrugsClinical', { + allQueries: { + + }, + byQuery: { + 'study.drug': { + category: { + allowBlank: false, + shownInGrid: false, + defaultValue: 'Clinical' + } + } + } +}); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js index 1543cd60d..2e02d1137 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/RoomLayoutPanel.js @@ -234,6 +234,36 @@ Ext4.define('ONPRC.panel.RoomLayoutPanel', { style: 'margin-bottom: 10px;', border: false }); + + //Modified: 8-19-2019 R. Blasa Added Divider Legends Not eeded at this time + currentSection.push({ + // html: 'List of cage slides, and the display letters they represent:

    ' + + // ' Infant Feeding Slide ---------> IFS
    ' + + // ' Clear Slide -----------------------> C
    ' + + // ' Extension Solid Slide --------> ES
    ' + + // ' Extension Mesh Slide -------> EM
    ' + + // ' Window Slide -------------------> W
    ' + + // ' Double Mesh Slides ----------> DM
    ' + + // ' Double Solid Slides -----------> DS
    ' + + // ' Window Mesh Slide ----------> WM
    ' + + // ' Backward Grooming Slide -> B


    ', + // + // + // }, { + //Added: 10-9-2019 R.Blasa + xtype: 'button', + text: 'Slide Descriptions', + scope: this, + style: 'margin-bottom: 10px;', + handler: function(btn){ + + var url = LABKEY.ActionURL.buildURL('onprc_ehr', 'SliderDefinition', this.containerPath); + window.open(url); + }, + + style: 'margin-bottom: 10px;', + border: false + }); } table = ONPRC.panel.RoomLayoutPanel.getRowBlockCfg(maxCage); @@ -378,8 +408,10 @@ Ext4.define('ONPRC.panel.RoomLayoutPanel', { defaults: { border: false }, - items: [{ - html: row.get('cage_type') == 'No Cage' ? 'No Cage' : ('' + ri + colIdx + '' + (cageType.sqft ? ' (' + (cageType.sqft / cageType.cageslots)+ suffix + ')' : '') + ''), + + //Modified: 4-8-2020 R.Blasa Contains symbol representing divider types + items: [{ + html: row.get('cage_type') == 'No Cage' ? 'No Cage' : ('' + ri + colIdx + '' + (cageType.sqft ? ' (' + (cageType.sqft / cageType.cageslots)+ suffix + ')' : '') + (dividerInfo.displaychar ? ' [' + (dividerInfo.displaychar) + ']' : '') + ''), bodyStyle: { 'background-color': 'transparent' }, diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js index 53721355f..64a99c175 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/SnapshotPanel.js @@ -156,6 +156,7 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { if (this.showExtendedInformation){ items[0].items = items[0].items.concat(this.getExtendedItems()); + } items[0].items = items[0].items.concat([{ @@ -165,6 +166,15 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { emptyText: 'There are no active medications' }]); + + //Sdded: 10-28-2019 R.Blasa + items[0].items = items[0].items.concat([{ + name: 'sdrug', + xtype: 'ehr-snapshotchildpanel', + headerLabel: 'Sustained Release Medication', + emptyText: 'There are no active medications' + }]); + if (this.showActionsButton){ items.push({ xtype: 'onprc_ehr-clinicalactionsbutton', //Modified: 6-13-2016 R.Blasa @@ -237,6 +247,8 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { //Added: 12-20-2018 R.Blasa this.appendLastKnownLocationResults(toSet, results.getLastKnownlocation()); + //Added: 10-4-2019 R.Bl;asa + this.appendDrugRecords(toSet, results.getActiveDrugs()); if (this.showExtendedInformation){ this.appendBirthResults(toSet, results.getBirthInfo(), results.getBirth()); @@ -379,8 +391,85 @@ Ext4.define('onprc_ehr.panel.SnapshotPanel', { }, + //Added: 10-4-2019 R.Blasa Display 72 hour Drug's given + appendDrugRecords2: function(toSet, results){ + var values = []; + if (results) + { + Ext4.each(results, function(row){ + var foster = row.FosterChild; + values.push(foster); + + }, this); + } + + toSet['fosterinfants'] = values.length ? values.join('
    ') : 'None'; + + }, + + //Added: 10-7-2019 R.Blasa + appendDrugRecords: function(toSet, rows){ + var el = this.down('panel[name=sdrug]'); + if (!el) + return; + + if (rows && rows.length){ + Ext4.each(rows, function(r){ + if (r.date){ + var date = LDK.ConvertUtils.parseDate(r.date); + //Modified: 11-6-2019 R.Blasa Compute elapse time in hours + var now = new Date(); + r.ElapseHours = Ext4.util.Format.round(Ext4.Date.getElapsed(date, now) / (1000 * 60 *60), 0); + + } + if (r.enddate){ + var enddate = LDK.ConvertUtils.parseDate(r.enddate); + + + } + }, this); + } + + el.appendTable({ + rows: rows + }, this.getDrugColumns()); + }, + + getDrugColumns: function(){ + return [{ + name: 'meaning', + label: 'Medication' + + },{ + name: 'amountAndVolume', + label: 'Amount', + attrs: { + style: 'white-space: normal !important;"' + } + },{ + name: 'route', + label: 'Route' + },{ + name: 'date', + label: 'Start Date' + },{ + name: 'ElapseHours', + label: 'Hours Elapsed' + + },{ + name: 'enddate', + label: 'End Date' + + },{ + name: 'remark', + label: 'Remark' + },{ + name: 'category', + label: 'Category' + }]; + }, appendWeightResults: function(toSet, results){ var text = []; diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index d2fcf0002..3a903031a 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -67,6 +67,7 @@ import org.labkey.onprc_ehr.demographics.CagematesDemographicsProvider; import org.labkey.onprc_ehr.demographics.FosterChildDemographicsProvider; import org.labkey.onprc_ehr.demographics.HousingDemographicsProvider; +import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.demographics.ParentsDemographicsProvider; import org.labkey.onprc_ehr.demographics.PregnancyConfirmDemographicsProvider; import org.labkey.onprc_ehr.demographics.SourceDemographicsProvider; @@ -251,6 +252,10 @@ private void registerEHRResources() //Added: 7-18-2018 R.Blasa EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageRecordWindow.js"), this); + //Added: 10-7-2019 R.Blasa + EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/TreatmentDrugsClinical.js"), this); + + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single Housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=demographicsPaired&query.viewName=Single Housed"), "Commonly Used Queries"); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "Find Animals Housed In A Given Room/Cage At A Specific Time", this, DetailsURL.fromString("/ehr/housingOverlaps.view?groupById=1"), "Commonly Used Queries"); @@ -430,8 +435,14 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(DrugRequestBulkEditFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(LabworkRequestBulkEditFormType.class, this)); - //Added: 5/23/2019 Kollil -// EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PMICRequestFormType.class, this)); + //Added: 5/23/2019 Kolli + // EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PMICRequestFormType.class, this)); + + //Added: 8/10/2019 Kolli +// EHRService.get().registerFormType(new DefaultDataEntryFormFactory(IPCRequestFormType.class, this)); + + //Added: 7/10/2019 by Kolli +// EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PMICDataEntryFormType.class, this)); // Added: 11-21-2017 R.Blasa EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ProcedureRequestBulkEditFormType.class, this)); @@ -445,6 +456,8 @@ public String toString() //Added: 4-5-2017 R.Blasa EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NHPRProcessingFormType.class, this)); + //Added: 11-4-2019 R.Blasa + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(TBTestObservationFormType.class, this)); //single section forms EHRService.get().registerSingleFormOverride(new SingleQueryFormProvider(this, "study", "treatment_order", new MedicationsQueryFormSection("study", "Treatment Orders", "Medication/Treatment Orders"))); @@ -480,6 +493,12 @@ public String toString() //Created: 4-7-2015-10-2017 R.Blasa EHRService.get().registerDemographicsProvider(new ActiveTreatmentsXDemographicsProvider(this)); + //Created: 12-18-2018 R.Blasa + EHRService.get().registerDemographicsProvider(new LastHousingDemographicsProvider(this)); + + //Created: 10-4-2019 R.Blasa + EHRService.get().registerDemographicsProvider(new ActiveDrugsGivenDemographicsProvider(this)); + //buttons EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "my_tasks"); EHRService.get().registerMoreActionsButton(new DiscardTaskButton(this), "ehr", "tasks"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBObservationFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBObservationFormSection.java new file mode 100644 index 000000000..7a3ff4041 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBObservationFormSection.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.EHRService; +import org.labkey.api.ehr.dataentry.AbstractFormSection; +import org.labkey.api.ehr.dataentry.SimpleGridPanel; + + +//Created: 6-27-2019 R.Blasa + +public class TBObservationFormSection extends SimpleGridPanel +{ + public TBObservationFormSection() + { + this(EHRService.FORM_SECTION_LOCATION.Body); + setTemplateMode(AbstractFormSection.TEMPLATE_MODE.NONE); + } + + public TBObservationFormSection(EHRService.FORM_SECTION_LOCATION location) + { + super("study", "Clinical Observations", "TB TST Scores", location); + + + + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java new file mode 100644 index 000000000..3b3210202 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.dataentry; + +import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.TaskForm; +import org.labkey.api.ehr.dataentry.TaskFormSection; +import org.labkey.api.ehr.security.EHRClinicalEntryPermission; +import org.labkey.api.module.Module; +import org.labkey.api.view.template.ClientDependency; + +import java.util.Arrays; + +//Created: 6-27-2019 R.Blasa +public class TBTestObservationFormType extends TaskForm +{ + public static final String NAME = "TB TST Scores"; + + public TBTestObservationFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "TB TST Scores", "Clinical", Arrays.asList( + new TaskFormSection(), + new AnimalDetailsFormSection(), + new TBObservationFormSection() + + )); + + for (FormSection s : this.getFormSections()) + { + s.addConfigSource("TB_TestObservation"); + + } + + addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/TB_TestObservation.js")); + + addClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/TB_TST_Scores_Type.js")); + + + + } + + + + @Override + protected boolean canInsert() + { + if (!getCtx().getContainer().hasPermission(getCtx().getUser(), EHRClinicalEntryPermission.class)) + return false; + + return super.canInsert(); + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java index 6bd6f1c45..326191507 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java @@ -18,6 +18,7 @@ import org.labkey.api.ehr.EHRService; import org.labkey.api.ehr.dataentry.AnimalDetailsFormSection; import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; import org.labkey.api.ehr.dataentry.TaskForm; import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.ehr.dataentry.DrugAdministrationFormSection; @@ -50,6 +51,14 @@ public TreatmentsFormType(DataEntryFormContext ctx, Module owner) new TreatmentOrdersFormSection() )); + //Added: 10-7-2019 R.Blasa + for (FormSection s : this.getFormSections()) + { + s.addConfigSource("TreatmentDrugsClinical"); + + } + addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/TreatmentDrugsClinical.js")); + if (ctx.getContainer().getActiveModules().contains(ModuleLoader.getInstance().getModule("onprc_billing"))) { addSection(new MiscChargesFormSection(EHRService.FORM_SECTION_LOCATION.Body)); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveDrugsGivenDemographicsProvider.java b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveDrugsGivenDemographicsProvider.java new file mode 100644 index 000000000..3305e0603 --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/demographics/ActiveDrugsGivenDemographicsProvider.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.demographics; + +import org.labkey.api.data.CompareType; +import org.labkey.api.data.SimpleFilter; +import org.labkey.api.ehr.demographics.AbstractListDemographicsProvider; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; +import org.apache.commons.lang3.time.DateUtils; + +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.Calendar; + + +//Created: 10-4-2019 R.Blasa 72 hours Drugs Given +public class ActiveDrugsGivenDemographicsProvider extends AbstractListDemographicsProvider +{ + public ActiveDrugsGivenDemographicsProvider(Module module) + { + super(module, "study", "DrugsGiven72hours", "activeDrugs"); + _supportsQCState = false; + } + + protected Set getFieldKeys() + { + Set keys = new HashSet(); + keys.add(FieldKey.fromString("Id")); + keys.add(FieldKey.fromString("code")); + keys.add(FieldKey.fromString("meaning")); + keys.add(FieldKey.fromString("enddate")); + keys.add(FieldKey.fromString("date")); + keys.add(FieldKey.fromString("route")); + keys.add(FieldKey.fromString("ElapseHours")); + keys.add(FieldKey.fromString("amountAndVolume")); + + keys.add(FieldKey.fromString("remark")); + keys.add(FieldKey.fromString("category")); + + return keys; + } + + @Override + public boolean requiresRecalc(String schema, String query) + { + return ("study".equalsIgnoreCase(schema) && ("drug".equalsIgnoreCase(query) || "treatment_order".equalsIgnoreCase(query))) ; + + } +} diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ObeseFlagNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ObeseFlagNotification.java index da1f6f5b7..8b7ed72c5 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ObeseFlagNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ObeseFlagNotification.java @@ -130,6 +130,15 @@ private void ObeseFlagprocess(Container c, User u, final StringBuilder msg) colKeys.add(FieldKey.fromString("enddate")); colKeys.add(FieldKey.fromString("flag/category")); colKeys.add(FieldKey.fromString("flag/value")); + +// Added: 10-25-2019 R.Blasa + colKeys.add(FieldKey.fromString("Id/assignedVet/assignedVet")); + colKeys.add(FieldKey.fromString("Id/MostRecentWeight/MostRecentWeight")); + colKeys.add(FieldKey.fromString("Id/curLocation/room")); + colKeys.add(FieldKey.fromString("Id/curLocation/cage")); + + + final Map columns = QueryService.get().getColumns(ti, colKeys); TableSelector ts = new TableSelector(ti, columns.values(), filter, sort); @@ -142,7 +151,7 @@ private void ObeseFlagprocess(Container c, User u, final StringBuilder msg) { //Create header information on this report msg.append(""); - msg.append("\n"); + msg.append("\n"); ts.forEach(new Selector.ForEachBlock() @@ -156,7 +165,20 @@ public void exec(ResultSet rs) throws SQLException Date datess = results.getDate(FieldKey.fromString("date")); String categorys = results.getString(FieldKey.fromString("flag/category")); String valuess = results.getString(FieldKey.fromString("flag/value")); - msg.append("\n"); + +// Added: 10-25-2019 R,Blasa + String vetname = results.getString(FieldKey.fromString("Id/assignedVet/assignedVet")); + String weights = results.getString(FieldKey.fromString("Id/MostRecentWeight/MostRecentWeight")); + String rooms = results.getString(FieldKey.fromString("Id/curLocation/room")); + String cages = results.getString(FieldKey.fromString("Id/curLocation/cage")); + + + + msg.append("" + + "" + + "\n"); + } }); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java index 665149f2b..1ff865f6c 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotification.java @@ -87,7 +87,6 @@ public String getMessageBodyHTML(Container c, User u) Date now = new Date(); msg.append("This email contains any treatments not marked as completed. It was run on: " + getDateFormat(c).format(now) + " at " + _timeFormat.format(now) + ".

    "); - processPostOpsTreatments(c, u, msg, new Date()); return msg.toString(); @@ -176,13 +175,111 @@ public void exec(ResultSet object) throws SQLException msg.append("Treatments:

    "); msg.append("There are " + (totals.get(completed) + totals.get(incomplete)) + " scheduled treatments on or before " + _timeFormat.format(maxDate) + ". Click here to view them. Of these, " + totals.get(completed) + " have been marked completed.

    \n"); + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + //Add code to display report, by Kollil + + TableInfo ti1 = QueryService.get().getUserSchema(u, c, "study").getTable("treatmentSchedulePostOps"); + + //All fields + Set columns1 = new HashSet<>(); + columns1.add(FieldKey.fromString("id")); + columns1.add(FieldKey.fromString("calculated_status")); + columns1.add(FieldKey.fromString("treatmentStatus")); + columns1.add(FieldKey.fromString("room")); + columns1.add(FieldKey.fromString("cage")); + columns1.add(FieldKey.fromString("date")); + columns1.add(FieldKey.fromString("startDate")); + columns1.add(FieldKey.fromString("endDate")); + columns1.add(FieldKey.fromString("dayselapsed")); + columns1.add(FieldKey.fromString("category")); + columns1.add(FieldKey.fromString("medication")); + columns1.add(FieldKey.fromString("volume")); + columns1.add(FieldKey.fromString("vol_units")); + columns1.add(FieldKey.fromString("concentration")); + columns1.add(FieldKey.fromString("conc_units")); + columns1.add(FieldKey.fromString("amountWithUnits")); + columns1.add(FieldKey.fromString("amountAndVolume")); + columns1.add(FieldKey.fromString("dosage")); + columns1.add(FieldKey.fromString("dosage_units")); + columns1.add(FieldKey.fromString("frequency")); + columns1.add(FieldKey.fromString("route")); + columns1.add(FieldKey.fromString("reason")); + columns1.add(FieldKey.fromString("remark")); + columns1.add(FieldKey.fromString("performedby")); + + final Map colMap1 = QueryService.get().getColumns(ti1, columns1); + TableSelector ts1 = new TableSelector(ti1, colMap1.values(), filter, new Sort("id")); + ts1.setNamedParameters(params); + //url = getExecuteQueryUrl(c, "study", "treatmentSchedulePostOps", null) ; + total = ts1.getRowCount(); + + if (total == 0) + { + msg.append("There are no post op meds"); + } + else + { + msg.append("


    Post Op Meds:

    \n"); + msg.append("
    Monkey IDStart DateRemoval DateCategoryMeaning
    Monkey IDRoomCageCurrent Weight (kg)Start DateRemoval DateAssigned Vet
    " + Ids + "" + DateUtil.formatDateTime(c, datess) + "" + DateUtil.formatDateTime(c, enddates) + "" + categorys + "" + valuess + "
    " + Ids + "" + rooms + "" + cages + "" + " " + weights + "" + + DateUtil.formatDateTime(c, datess) + "" + DateUtil.formatDateTime(c, enddates) + "" + " " + vetname + "
    "); + msg.append(""); + + ts1.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet object) throws SQLException + + { + Results rs = new ResultsImpl(object, colMap1); + String status = rs.getString("TreatmentStatus"); + if ("completed".equalsIgnoreCase(status)) + { + msg.append(""); + } + else { + //If not "completed", highlight the record with yellow color + msg.append(""); + } + + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + } + }); + + msg.append("
    IdStatusTreatment StatusRoomCageTreatment DateTreatment Start DateTreatment End DateDays ElapsedCategoryTreatmentVolumeVolume UnitsDrug ConcConc UnitsAmountAmount And VolumeDosageDosage UnitsFrequencyRouteReasonRemarkOrdered By
    " + rs.getString("id") + "" + rs.getString("calculated_status") + "" + rs.getString("TreatmentStatus") + "" + rs.getString("room") + "" + rs.getString("cage") + "" + rs.getString("date") + "" + rs.getString("startDate") + "" + rs.getString("endDate") + "" + rs.getString("dayselapsed") + "" + rs.getString("category") + "" + rs.getString("medication") + "" + rs.getString("volume") + "" + rs.getString("vol_units") + "" + rs.getString("concentration") + "" + rs.getString("conc_units") + "" + rs.getString("amountWithUnits") + "" + rs.getString("amountAndVolume") + "" + rs.getString("dosage") + "" + rs.getString("dosage_units") + "" + rs.getString("frequency") + "" + rs.getString("route") + "" + rs.getString("reason") + "" + rs.getString("remark") + "" + rs.getString("performedby") + "
    "); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + if (totals.get(incomplete) == 0) { - msg.append("All treatments scheduled prior to " + _timeFormat.format(maxDate) + " have been marked complete as of " + getDateTimeFormat(c).format(curDate) + ".

    \n"); + msg.append("
    All treatments scheduled prior to " + _timeFormat.format(maxDate) + " have been marked complete as of " + getDateTimeFormat(c).format(curDate) + ".

    \n"); } else { - msg.append("There are " + totals.get(incomplete) + " treatments that have not been marked complete:

    \n"); + msg.append("
    There are " + totals.get(incomplete) + " treatments that have not been marked complete:

    \n"); msg.append(""); for (String area : totalByArea.keySet()) @@ -194,5 +291,6 @@ public void exec(ResultSet object) throws SQLException } msg.append("
    \n"); } + } } \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationSecondary.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationSecondary.java index 4f4550474..338dae536 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationSecondary.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationSecondary.java @@ -171,6 +171,104 @@ public void exec(ResultSet object) throws SQLException msg.append("Treatments:

    "); msg.append("There are " + (totals.get(completed) + totals.get(incomplete)) + " scheduled treatments on or before " + _timeFormat.format(maxDate) + ". Click here to view them. Of these, " + totals.get(completed) + " have been marked completed.

    \n"); + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + //Add code to display report, by Kollil + + TableInfo ti1 = QueryService.get().getUserSchema(u, c, "study").getTable("treatmentSchedulePostOps"); + + //All fields + Set columns1 = new HashSet<>(); + columns1.add(FieldKey.fromString("id")); + columns1.add(FieldKey.fromString("calculated_status")); + columns1.add(FieldKey.fromString("treatmentStatus")); + columns1.add(FieldKey.fromString("room")); + columns1.add(FieldKey.fromString("cage")); + columns1.add(FieldKey.fromString("date")); + columns1.add(FieldKey.fromString("startDate")); + columns1.add(FieldKey.fromString("endDate")); + columns1.add(FieldKey.fromString("dayselapsed")); + columns1.add(FieldKey.fromString("category")); + columns1.add(FieldKey.fromString("medication")); + columns1.add(FieldKey.fromString("volume")); + columns1.add(FieldKey.fromString("vol_units")); + columns1.add(FieldKey.fromString("concentration")); + columns1.add(FieldKey.fromString("conc_units")); + columns1.add(FieldKey.fromString("amountWithUnits")); + columns1.add(FieldKey.fromString("amountAndVolume")); + columns1.add(FieldKey.fromString("dosage")); + columns1.add(FieldKey.fromString("dosage_units")); + columns1.add(FieldKey.fromString("frequency")); + columns1.add(FieldKey.fromString("route")); + columns1.add(FieldKey.fromString("reason")); + columns1.add(FieldKey.fromString("remark")); + columns1.add(FieldKey.fromString("performedby")); + + final Map colMap1 = QueryService.get().getColumns(ti1, columns1); + TableSelector ts1 = new TableSelector(ti1, colMap1.values(), filter, new Sort("id")); + ts1.setNamedParameters(params); + //url = getExecuteQueryUrl(c, "study", "treatmentSchedulePostOps", null) ; + total = ts1.getRowCount(); + + if (total == 0) + { + msg.append("There are no post op meds"); + } + else + { + msg.append("


    Post Op Meds:

    \n"); + msg.append("
    "); + msg.append(""); + + ts1.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet object) throws SQLException + + { + Results rs = new ResultsImpl(object, colMap1); + String status = rs.getString("TreatmentStatus"); + if ("completed".equalsIgnoreCase(status)) + { + msg.append(""); + } + else { + //If not "completed", highlight the record with yellow color + msg.append(""); + } + + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + } + }); + + msg.append("
    IdStatusTreatment StatusRoomCageTreatment DateTreatment Start DateTreatment End DateDays ElapsedCategoryTreatmentVolumeVolume UnitsDrug ConcConc UnitsAmountAmount And VolumeDosageDosage UnitsFrequencyRouteReasonRemarkOrdered By
    " + rs.getString("id") + "" + rs.getString("calculated_status") + "" + rs.getString("TreatmentStatus") + "" + rs.getString("room") + "" + rs.getString("cage") + "" + rs.getString("date") + "" + rs.getString("startDate") + "" + rs.getString("endDate") + "" + rs.getString("dayselapsed") + "" + rs.getString("category") + "" + rs.getString("medication") + "" + rs.getString("volume") + "" + rs.getString("vol_units") + "" + rs.getString("concentration") + "" + rs.getString("conc_units") + "" + rs.getString("amountWithUnits") + "" + rs.getString("amountAndVolume") + "" + rs.getString("dosage") + "" + rs.getString("dosage_units") + "" + rs.getString("frequency") + "" + rs.getString("route") + "" + rs.getString("reason") + "" + rs.getString("remark") + "" + rs.getString("performedby") + "
    "); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + if (totals.get(incomplete) == 0) { msg.append("All treatments scheduled prior to " + _timeFormat.format(maxDate) + " have been marked complete as of " + getDateTimeFormat(c).format(curDate) + ".

    \n"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java index 88bd2cae4..57a997647 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/TreatmentAlertsPostOpsNotificationThird.java @@ -167,6 +167,104 @@ public void exec(ResultSet object) throws SQLException msg.append("Treatments:

    "); msg.append("There are " + (totals.get(completed) + totals.get(incomplete)) + " scheduled treatments on or before " + _timeFormat.format(maxDate) + ". Click here to view them. Of these, " + totals.get(completed) + " have been marked completed.

    \n"); + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + //Add code to display report, by Kollil + + TableInfo ti1 = QueryService.get().getUserSchema(u, c, "study").getTable("treatmentSchedulePostOps"); + + //All fields + Set columns1 = new HashSet<>(); + columns1.add(FieldKey.fromString("id")); + columns1.add(FieldKey.fromString("calculated_status")); + columns1.add(FieldKey.fromString("treatmentStatus")); + columns1.add(FieldKey.fromString("room")); + columns1.add(FieldKey.fromString("cage")); + columns1.add(FieldKey.fromString("date")); + columns1.add(FieldKey.fromString("startDate")); + columns1.add(FieldKey.fromString("endDate")); + columns1.add(FieldKey.fromString("dayselapsed")); + columns1.add(FieldKey.fromString("category")); + columns1.add(FieldKey.fromString("medication")); + columns1.add(FieldKey.fromString("volume")); + columns1.add(FieldKey.fromString("vol_units")); + columns1.add(FieldKey.fromString("concentration")); + columns1.add(FieldKey.fromString("conc_units")); + columns1.add(FieldKey.fromString("amountWithUnits")); + columns1.add(FieldKey.fromString("amountAndVolume")); + columns1.add(FieldKey.fromString("dosage")); + columns1.add(FieldKey.fromString("dosage_units")); + columns1.add(FieldKey.fromString("frequency")); + columns1.add(FieldKey.fromString("route")); + columns1.add(FieldKey.fromString("reason")); + columns1.add(FieldKey.fromString("remark")); + columns1.add(FieldKey.fromString("performedby")); + + final Map colMap1 = QueryService.get().getColumns(ti1, columns1); + TableSelector ts1 = new TableSelector(ti1, colMap1.values(), filter, new Sort("id")); + ts1.setNamedParameters(params); + //url = getExecuteQueryUrl(c, "study", "treatmentSchedulePostOps", null) ; + total = ts1.getRowCount(); + + if (total == 0) + { + msg.append("There are no post op meds"); + } + else + { + msg.append("


    Post Op Meds:

    \n"); + msg.append(""); + msg.append(""); + + ts1.forEach(new Selector.ForEachBlock() + { + @Override + public void exec(ResultSet object) throws SQLException + + { + Results rs = new ResultsImpl(object, colMap1); + String status = rs.getString("TreatmentStatus"); + if ("completed".equalsIgnoreCase(status)) + { + msg.append(""); + } + else { + //If not "completed", highlight the record with yellow color + msg.append(""); + } + + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + } + }); + + msg.append("
    IdStatusTreatment StatusRoomCageTreatment DateTreatment Start DateTreatment End DateDays ElapsedCategoryTreatmentVolumeVolume UnitsDrug ConcConc UnitsAmountAmount And VolumeDosageDosage UnitsFrequencyRouteReasonRemarkOrdered By
    " + rs.getString("id") + "" + rs.getString("calculated_status") + "" + rs.getString("TreatmentStatus") + "" + rs.getString("room") + "" + rs.getString("cage") + "" + rs.getString("date") + "" + rs.getString("startDate") + "" + rs.getString("endDate") + "" + rs.getString("dayselapsed") + "" + rs.getString("category") + "" + rs.getString("medication") + "" + rs.getString("volume") + "" + rs.getString("vol_units") + "" + rs.getString("concentration") + "" + rs.getString("conc_units") + "" + rs.getString("amountWithUnits") + "" + rs.getString("amountAndVolume") + "" + rs.getString("dosage") + "" + rs.getString("dosage_units") + "" + rs.getString("frequency") + "" + rs.getString("route") + "" + rs.getString("reason") + "" + rs.getString("remark") + "" + rs.getString("performedby") + "
    "); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + if (totals.get(incomplete) == 0) { msg.append("All treatments scheduled prior to " + _timeFormat.format(maxDate) + " have been marked complete as of " + getDateTimeFormat(c).format(curDate) + ".

    \n"); From 8c7b42839fa134059235f2459f7c804427a94db1 Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 19:12:56 -0700 Subject: [PATCH 08/49] Merge from onprc19.1 r.64769 to 64894 --- .../queries/onprc_billing/virologyAliases.sql | 2 +- .../onprc_billing/ONPRC_BillingModule.java | 2 + .../dataentry/ChargesFormType.java | 13 ++ .../ChargesVirologyCoreFormType.java | 32 ++-- .../security/ONPRCVirologyAccessRole.java | 49 +++++ .../ONPRCVirologyCoreEntryPermission.java | 28 +++ .../queries/study/GeneticValueRanking.sql | 12 ++ .../queries/study/demographicsAssignedVet.sql | 117 ++++++------ .../queries/study/vet_assignedResearch.sql | 39 ++-- .../queries/study/vet_assignedResource.sql | 40 +++-- .../study/vet_assignmentDemographics.sql | 167 +++++++++++------- .../resources/views/printableReports.html | 68 +++++++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 7 + .../onprc_ehr/dataentry/BiopsyFormType.java | 18 +- .../dataentry/MedSignoffFormType.java | 17 ++ .../DefaultSustainedReleaseDatasource.java | 81 +++++++++ 16 files changed, 535 insertions(+), 157 deletions(-) create mode 100644 onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyAccessRole.java create mode 100644 onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyCoreEntryPermission.java create mode 100644 onprc_ehr/resources/queries/study/GeneticValueRanking.sql create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/history/DefaultSustainedReleaseDatasource.java diff --git a/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql b/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql index 950db25a1..6a0075823 100644 --- a/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql +++ b/onprc_billing/resources/queries/onprc_billing/virologyAliases.sql @@ -6,4 +6,4 @@ FROM "/onprc/admin/finance/public".onprc_billing_public.aliases --WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate >= now() )) -- including the aliases that expired 30 days ago from today's date. This provision is given to the PIs to enter the previous month charges. By Kolli on 7/6/19 WHERE (budgetstartdate IS NOT NULL AND (budgetEndDate IS NULL OR budgetEndDate >= TIMESTAMPADD('SQL_TSI_DAY', -30, now()) )) -OR alias in (Select alias from "/onprc/admin/finance".lists.Special_Aliases Where category like 'Virology') +OR alias in (Select alias from lists.Special_Aliases Where category like 'Virology') diff --git a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java index 29207c994..372b747f6 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java +++ b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java @@ -57,6 +57,7 @@ import org.labkey.onprc_billing.security.ONPRCAliasEditorRole; import org.labkey.onprc_billing.security.ONPRCBillingAdminPermission; import org.labkey.onprc_billing.security.ONPRCBillingAdminRole; +import org.labkey.onprc_billing.security.ONPRCVirologyAccessRole; import org.labkey.onprc_billing.table.ChargeableItemsCustomizer; import org.labkey.onprc_billing.table.ONPRC_BillingCustomizer; @@ -102,6 +103,7 @@ protected void init() RoleManager.registerRole(new ONPRCBillingAdminRole()); RoleManager.registerRole(new ONPRCAliasEditorRole()); + RoleManager.registerRole(new ONPRCVirologyAccessRole()); } @Override diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java index b493659a9..8c8181987 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesFormType.java @@ -55,6 +55,19 @@ public boolean isVisible() { return false; } +// Added: 12-3-2019 R.blasa + Group j = GroupManager.getGroup(getCtx().getContainer(), "Pathology External Entry", GroupEnumType.SITE); + if (j != null && getCtx().getUser().isInGroup(j.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + + // Added: 12-3-2019 R.blasa + Group L = GroupManager.getGroup(getCtx().getContainer(), "Virology Core", GroupEnumType.SITE); + if (L != null && getCtx().getUser().isInGroup(L.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } return super.isVisible(); } } diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java index a5a4632d3..d707eeddf 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java @@ -7,6 +7,8 @@ import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.module.Module; import org.labkey.api.view.template.ClientDependency; +import org.labkey.onprc_billing.security.ONPRCBillingAdminPermission; +import org.labkey.onprc_billing.security.ONPRCVirologyCoreEntryPermission; import org.labkey.security.xml.GroupEnumType; import org.labkey.api.security.GroupManager; import org.labkey.api.security.permissions.AdminPermission; @@ -33,17 +35,6 @@ public ChargesVirologyCoreFormType(DataEntryFormContext ctx, Module owner) } - //Added: 11/1/2018 R.Blasa Hide this menu when SLA users are accessing their exit records - @Override - public boolean isVisible() - { - Group g = GroupManager.getGroup(getCtx().getContainer(), "SLA Users", GroupEnumType.SITE); - if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) - { - return false; - } - return super.isVisible(); - } @Override protected List getMoreActionButtonConfigs() @@ -53,4 +44,23 @@ protected List getMoreActionButtonConfigs() return defaultButtons; } + +// Added: 12-3-2019 R.Blasa +@Override +public boolean canInsert() +{ + if (!getCtx().getContainer().hasPermission(getCtx().getUser(), ONPRCVirologyCoreEntryPermission.class)) + return false; + + return super.canInsert(); +} + + @Override + public boolean canRead() + { + if (!getCtx().getContainer().hasPermission(getCtx().getUser(), ONPRCVirologyCoreEntryPermission.class)) + return false; + + return super.canRead(); + } } diff --git a/onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyAccessRole.java b/onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyAccessRole.java new file mode 100644 index 000000000..a32a0ab34 --- /dev/null +++ b/onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyAccessRole.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_billing.security; + +import org.labkey.api.data.Container; +import org.labkey.api.ehr.security.EHRProjectEditPermission; +import org.labkey.api.module.ModuleLoader; +import org.labkey.api.security.SecurableResource; +import org.labkey.api.security.SecurityPolicy; +import org.labkey.api.security.permissions.DeletePermission; +import org.labkey.api.security.permissions.InsertPermission; +import org.labkey.api.security.permissions.ReadPermission; +import org.labkey.api.security.permissions.UpdatePermission; +import org.labkey.api.security.roles.AbstractModuleScopedRole; +import org.labkey.api.security.roles.AbstractRole; +import org.labkey.onprc_billing.ONPRC_BillingModule; + +/** + * User: bimber + * Date: 1/7/13 + * Time: 4:53 PM + */ +public class ONPRCVirologyAccessRole extends AbstractModuleScopedRole +{ + public ONPRCVirologyAccessRole() + { + super("ONPRC Billing VirologyCore Entry", "Users with this role are able to make changes to the billing and finance tables", ONPRC_BillingModule.class, + ReadPermission.class, + InsertPermission.class, + UpdatePermission.class, + DeletePermission.class, + ONPRCVirologyCoreEntryPermission.class + + ); + } +} diff --git a/onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyCoreEntryPermission.java b/onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyCoreEntryPermission.java new file mode 100644 index 000000000..b852ba34b --- /dev/null +++ b/onprc_billing/src/org/labkey/onprc_billing/security/ONPRCVirologyCoreEntryPermission.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_billing.security; + +import org.labkey.api.security.permissions.AbstractPermission; + +//Created: 12-3-2019 R.Blasa +public class ONPRCVirologyCoreEntryPermission extends AbstractPermission +{ + public ONPRCVirologyCoreEntryPermission() + { + super("ONPRCVirologyCoreEntryPermission", "Can insert charges in the EHR"); + } +} + diff --git a/onprc_ehr/resources/queries/study/GeneticValueRanking.sql b/onprc_ehr/resources/queries/study/GeneticValueRanking.sql new file mode 100644 index 000000000..52d23e33a --- /dev/null +++ b/onprc_ehr/resources/queries/study/GeneticValueRanking.sql @@ -0,0 +1,12 @@ +Select +Id, +meanKinship, +zscore, +genomeUniqueness, +totalOffspring, +livingOffspring, +assignments as TotalAssignments, +condition, +value as GeneticValue, +rank +From "/ONPRC/DCM/NHP Resources".lists.GeneticValue \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql index 2c1ec0840..bdc172201 100644 --- a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql +++ b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql @@ -1,86 +1,73 @@ --Update 3/7/2019 load to test Select -Distinct -d.Id, -d.room.area as Area, -d.room, -d.CaseVet, -d.protocol, -d.ProtocolPI, -d.Calculated_status, -Case - -- when d.DeceaseDAssignedVet is not null then d.DeceaseDAssignedVet - when d.caseVet is not null then d.CaseVet - when p1.userId is not null then p1.userId.displayName - when p2.userId is not null then p2.userId.DisplayName - when v1.userId is not null then v1.userId.displayName - when v2.userId is not null then v2.userId.DisplayName - when v3.userId is not null then v3.userId.DisplayName - when v4.userId is not null then v4.userId.DisplayName - when p3.userId is not null then p3.userId.DisplayName - when p4.userId is not null then p4.userId.DisplayName - when v5.userId is not null then v5.userId.DisplayName - when v6.userId is not null then v6.userId.DisplayName - when h1.userId is not null then h1.userId.DisplayName - when h2.userId is not null then h2.userId.DisplayName + Distinct + d.Id, + d.room.area as Area, + d.room, + d.CaseVet, + d.protocol, + d.ProtocolPI, + d.Calculated_status, + Case + -- when d.DeceaseDAssignedVet is not null then d.DeceaseDAssignedVet + when d.caseVet is not null then d.CaseVet + when p1.userId is not null then p1.userId.displayName + when p2.userId is not null then p2.userId.DisplayName + when v1.userId is not null then v1.userId.displayName + when v2.userId is not null then v2.userId.DisplayName + when v3.userId is not null then v3.userId.DisplayName + when v4.userId is not null then v4.userId.DisplayName + when p3.userId is not null then p3.userId.DisplayName + when p4.userId is not null then p4.userId.DisplayName + when v5.userId is not null then v5.userId.DisplayName + when v6.userId is not null then v6.userId.DisplayName + when h1.userId is not null then h1.userId.DisplayName + when h2.userId is not null then h2.userId.DisplayName -LEFT JOIN ( -Select a2.id, -a2. vetAssigned as vetName, -a2.protocol -from resourceAssigned a2 ) -a2 ON (a2.Id = d.Id) + End as AssignedVet, -Case - -- when d.DeceaseDAssignedVet is not null then 'Deceased or Shipped NHP' - when d.caseVet is not null then 'Open Case' - when p1.userId is not null then 'Room Priority' - when p2.userId is not null then 'Area Priority' - When p3.userId is not null then 'Protocol Room Priority' - When p4.userId is not null then 'Protocol Area Priority' - when v1.userId is not null then 'Protocol Research Room' - when v2.userId is not null then 'Protocol Research Area' - when v3.userId is not null then 'Protocol Resource Room' - when v4.userId is not null then 'Protocol Resource Area' - when v5.userId is not null then 'Protocol Research Only' - when v6.userId is not null then 'Protocol Resource Only' + Case + -- when d.DeceaseDAssignedVet is not null then 'Deceased or Shipped NHP' + when d.caseVet is not null then 'Open Case' + when p1.userId is not null then 'Room Priority' + when p2.userId is not null then 'Area Priority' + When p3.userId is not null then 'Protocol Room Priority' + When p4.userId is not null then 'Protocol Area Priority' + when v1.userId is not null then 'Protocol Research Room' + when v2.userId is not null then 'Protocol Research Area' + when v3.userId is not null then 'Protocol Resource Room' + when v4.userId is not null then 'Protocol Resource Area' + when v5.userId is not null then 'Protocol Research Only' + when v6.userId is not null then 'Protocol Resource Only' + when h1.userId is not null then 'Room Only' + when h2.userId is not null then 'Area Only' --- SELECT --- a.Id, --- group_concat(distinct CAST(v.userId.displayName as varchar(120))) as vetNames, --- CAST(group_concat(distinct v.userId) as varchar(200)) as vetUserIds, --------- Need to only look at Vets on assignment as assigned vet for reseach protocols --- (Select distinct a2.project.protocol.displayname from study.assignment a2 where a2.project.protocol = v.protocol and a2.project.use_category.value = 'Research') as protocols ----- group_concat.use_cagte(distinct a.project.protocol.displayName) as protocols --- FROM study.assignment a --- JOIN onprc_ehr.vet_assignment v ON (a.project.protocol = v.protocol) --- WHERE a.enddateCoalesced >= curdate() OR CAST(a.enddateCoalesced AS DATE) = CAST(a.Id.demographics.lastDayAtCenter AS DATE) --- GROUP BY a.Id,v.protocol + End as AssignmentType FROM study.vet_assignmentDemographics d --this handles REsearch Protocol Room -Left Join onprc_ehr.vet_assignment v1 on (v1.protocol.displayName = d.protocol and v1.room = d.room and d.assignmentType = 'Research Assigned') + Left Join onprc_ehr.vet_assignment v1 on (v1.protocol.displayName = d.protocol and v1.room = d.room and d.assignmentType = 'Research Assigned') --this handles Research Protocol Area -Left Join onprc_ehr.vet_assignment v2 on (v2.protocol.displayName = d.protocol and v2.area = d.room.area and d.assignmentType = 'Research Assigned') + Left Join onprc_ehr.vet_assignment v2 on (v2.protocol.displayName = d.protocol and v2.area = d.room.area and d.assignmentType = 'Research Assigned') --this handles Resource Protocol Room -Left Join onprc_ehr.vet_assignment v3 on (v3.protocol.displayName = d.protocol and v3.room = d.room and d.assignmentType = 'Resource Assigned') + Left Join onprc_ehr.vet_assignment v3 on (v3.protocol.displayName = d.protocol and v3.room = d.room and d.assignmentType = 'Resource Assigned') --this handles Research Protocol Area -Left Join onprc_ehr.vet_assignment v4 on (v4.protocol.displayName = d.protocol and v4.area = d.room.area and d.assignmentType = 'Resource Assigned') + Left Join onprc_ehr.vet_assignment v4 on (v4.protocol.displayName = d.protocol and v4.area = d.room.area and d.assignmentType = 'Resource Assigned') --this handled Research Assigned No Additional Sekections -Left Join onprc_ehr.vet_assignment v5 on (v5.protocol.displayName = d.protocol and v5.room is null and v5.area is null and d.assignmentType = 'Research Assigned' ) + Left Join onprc_ehr.vet_assignment v5 on (v5.protocol.displayName = d.protocol and v5.room is null and v5.area is null and d.assignmentType = 'Research Assigned' ) --this handles resource Protocol Only -Left Join onprc_ehr.vet_assignment v6 on (v6.protocol.displayName = d.protocol and v6.room is null and v6.area is null and d.assignmentType = 'Resource Assigned' ) + Left Join onprc_ehr.vet_assignment v6 on (v6.protocol.displayName = d.protocol and v6.room is null and v6.area is null and d.assignmentType = 'Resource Assigned' ) --this handles when the room is a priorty -Left join onprc_ehr.vet_assignment p1 on (p1.room = d.room and p1.protocol is null and p1.priority = true) + Left join onprc_ehr.vet_assignment p1 on (p1.room = d.room and p1.protocol is null and p1.priority = true) --this handles when the room is a priorty- -Left join onprc_ehr.vet_assignment p2 on (p2.area = d.room.area and p2.protocol is null and p2.priority = true) + Left join onprc_ehr.vet_assignment p2 on (p2.area = d.room.area and p2.protocol is null and p2.priority = true) --THis handles when a priority is placed on Room and Protocol -- -Left Join onprc_ehr.vet_assignment p3 on (p3.protocol.displayName = d.protocol and p3.room = d.room and p3.priority = true) + Left Join onprc_ehr.vet_assignment p3 on (p3.protocol.displayName = d.protocol and p3.room = d.room and p3.priority = true) --THis handles when a priority is placed on Areaand Protocol - -Left Join onprc_ehr.vet_assignment p4 on (p4.protocol.displayName = d.protocol and p4.area = d.room.area and p4.priority = true) + Left Join onprc_ehr.vet_assignment p4 on (p4.protocol.displayName = d.protocol and p4.area = d.room.area and p4.priority = true) --these deal with assignment based on housing only -Left join onprc_ehr.vet_assignment h1 on (h1.room = d.room and h1.protocol is null and h1.area is null and h1.priority = false) -Left join onprc_ehr.vet_assignment h2 on (h2.area = d.room.area and h2.room is null and h2.protocol is null and h2.priority = false) + Left join onprc_ehr.vet_assignment h1 on (h1.room = d.room and h1.protocol is null and h1.area is null and h1.priority = false) + Left join onprc_ehr.vet_assignment h2 on (h2.area = d.room.area and h2.room is null and h2.protocol is null and h2.priority = false) --where d.id not like '[a-z]%' \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignedResearch.sql b/onprc_ehr/resources/queries/study/vet_assignedResearch.sql index 63027aedf..b56a12b5a 100644 --- a/onprc_ehr/resources/queries/study/vet_assignedResearch.sql +++ b/onprc_ehr/resources/queries/study/vet_assignedResearch.sql @@ -1,16 +1,35 @@ --20190410 - changed to address no assigned vet for protocol in research update1 --Iss was this was not loaded at the prodctuib level +SELECT distinct a.Id, + a.project, + a.project.use_category, + a.project.protocol, + a.project.protocol.investigatorID.lastName as PI, + a.date, + a.projectedRelease, + a.enddate, + a.assignCondition, + 'Research Assigned' as ProtocolType, + v.protocol.displayName as VetAssignedProtocol +FROM study.assignment a left outer join "/onprc/ehr".onprc_ehr.vet_assignment v on a.project.protocol = v.protocol +where (a.project.use_category = 'Research') + and a.date = CurDate() and a.date = a.enddate + and v.protocol is not null + +Union + SELECT a.Id, -a.project, -a.project.use_category, -a.project.protocol, -a.date, -a.projectedRelease, -a.enddate, -a.assignCondition, -'Research Assigned' as ProtocolType, -v.protocol as VetAssignedProtocol + a.project, + a.project.use_category, + a.project.protocol, + a.project.protocol.investigatorID.lastName as PI, + a.date, + a.projectedRelease, + a.enddate, + a.assignCondition, + 'Research Assigned' as ProtocolType, + v.protocol.displayName as VetAssignedProtocol FROM study.assignment a left outer join "/onprc/ehr".onprc_ehr.vet_assignment v on a.project.protocol = v.protocol where ((a.date <= Now() and a.enddate is null) and (a.project.use_category = 'Research')) -and v.protocol is not null \ No newline at end of file + and v.protocol is not null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/vet_assignedResource.sql b/onprc_ehr/resources/queries/study/vet_assignedResource.sql index c5c820e7c..a70c60432 100644 --- a/onprc_ehr/resources/queries/study/vet_assignedResource.sql +++ b/onprc_ehr/resources/queries/study/vet_assignedResource.sql @@ -1,11 +1,31 @@ SELECT a.Id, -a.project, -a.project.use_category, -a.project.protocol, -a.date, -a.projectedRelease, -a.enddate, -a.assignCondition, -'Resource Assigned' as ProtocolType -FROM study.assignment a -where ((a.date <= Now() and a.enddate is null) and (a.project.use_category != 'Research')) \ No newline at end of file + a.project, + a.project.use_category, + a.project.protocol, + a.project.protocol.investigatorID.lastName as PI, + a.date, + a.projectedRelease, + a.enddate, + a.assignCondition, + 'Resource Assigned' as ProtocolType, + v.protocol.displayName as VetAssignedProtocol +FROM study.assignment a left outer join "/onprc/ehr".onprc_ehr.vet_assignment v on a.project.protocol = v.protocol +where ((a.date <= Now() and a.enddate is null) and (a.project.use_category != 'Research')) + +UNION + +SELECT a.Id, + a.project, + a.project.use_category, + a.project.protocol, + a.project.protocol.investigatorID.lastName as PI, + a.date, + a.projectedRelease, + a.enddate, + a.assignCondition, + 'Resource Assigned' as ProtocolType, + v.protocol.displayName as VetAssignedProtocol +FROM study.assignment a left outer join "/onprc/ehr".onprc_ehr.vet_assignment v on a.project.protocol = v.protocol +where (a.project.use_category != 'Research') + and a.date = CurDate() and a.date = a.enddate + and v.protocol is not null diff --git a/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql b/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql index 94f87d60f..5dbfe2b4b 100644 --- a/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql +++ b/onprc_ehr/resources/queries/study/vet_assignmentDemographics.sql @@ -1,90 +1,139 @@ ---Reviewed 2/7/2019 to update from vet_AssignmentDemographics_new ---Is the depenency for vet_assignmentSelect ---Reviewed 2/7/2019 to update from vet_AssignmentDemographics_new ---Is the depenency for vet_assignmentSelect - SELECT -Distinct - -d.Id, -d.gender, -d.species, -d.geographic_origin, -d.birth, -d.death, -d.lastDayatCenter, -h.room.area, -h.room, -d.calculated_status, -TimeStampAdd('SQL_TSI_YEAR', -1,Now()) as LastYear, -n.assignedVet as DeceaseDAssignedVet, -c.vetNames as CaseVet, -c.category, - CASE - WHEN (n.id IS NOT null) THEN 'DECEASED or SHIPPED NHP' - WHEN (c.id IS NOT NULL) THEN 'Active Case' - WHen r1.id is not null then 'Research Assigned' - WHen r2.id is not null then 'Resource Assigned' - - ELSE 'P51' - END as assignmentType, - -Case - when r1.protocol is not null then r1.use_Category - when r2.protocol is not null then r2.use_category - else ' ' - End As use_category, + Distinct + + Case + when dm.Id is not null then dm.id + else d.id + end as id, + b.gender, + b.species, + b.geographic_origin, + b.date, + dm.death as death, + dm.LastDayAtCenter, + h.room.area, + h.room, +--d.calculated_status, + Case + when dm.id is not null then dm.calculated_status + When d2.id = d.id then 'Deceased' + wHEN D1.ID = d.id then 'Shipped' + Else 'Unknown' + End + As Calculated_status, + + TimeStampAdd('SQL_TSI_YEAR', -1,Now()) as LastYear, + Case + when dm.calculated_status = 'alive' then Null + When n.assignedVet is not Null then n.assignedVet + when d3.assignedvet is not null then d3.assignedVet + -- when cr.date >TimeStampAdd('SQL_TSI_MONTH', -12,Now()) then 'Remark OVer 12 Months' + --when (n.assignedVet is null or d3.assignedVet is Null and cr.date >TimeStampAdd('SQL_TSI_MONTH', -12,Now()) ) then '' + Else Null + End as DeceasedAssignedVet, + +--n.assignedVet as DeceaseDAssignedVet, + c.vetNames as CaseVet, + c.category, + CASE + -- When cr.id is null then 'No Clin Remarks Found' + WHen dm.id = d.id and dm.calculated_status = 'dead' then 'Deceased NHP' + When (d3.id = d.id) then 'Deceased NHP' + WHEN (n.id IS NOT null) THEN 'SHIPPED NHP' + WHEN (c.id IS NOT NULL) THEN 'Active Case' + WHen r1.id is not null then 'Research Assigned' + WHen r2.id is not null then 'Resource Assigned' + + ELSE 'P51' + END as assignmentType, + + Case + when r1.protocol is not null then r1.use_Category + when r2.protocol is not null then r2.use_category + else ' ' + End As use_category, --r1.use_Category, --This needs to be a case statement that resturned the protocol whether Resource or research with research being the priority -Case - when r1.protocol is not null then r1.protocol.displayName - when r2.protocol is not null then r2.protocol.displayName - else ' ' - End As protocol, + Case + when r1.protocol is not null then r1.VetAssignedProtocol + when r2.protocol is not null then r2.VetAssignedProtocol + else ' ' + End As protocol, + + Case + when r1.protocol is not null then r1.PI + when r2.protocol is not null then r2.PI + else ' ' + End As ProtocolPI --r1.protocol -FROM study.demographics d +FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.animal d ---Handles Deceased NHPs +--Handles Shipped NHPs LEFT JOIN ( select r.id, r.assignedVet - from study.demographics d1 join study.clinremarks r on d1.id = r.id - where d1.lastdayatCenter > TimeStampAdd('SQL_TSI_month', -12,Now()) + from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.departure d1 join study.clinremarks r on d1.id = r.id + where d1.date > TimeStampAdd('SQL_TSI_month', -12,Now()) and r.date = (Select Max(r1.date) from study.clinremarks r1 where r1.id = d1.id)) n on (n.Id =d.id) +--Handles Deceased NHPs + + LEFT JOIN ( + select d1.id, r.assignedVet + + + from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.demographics d1 join + Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.clinremarks r on d1.id = r.id + where (d1.date > TimeStampAdd('SQL_TSI_month', -12,Now()) and d1.calculated_status = 'dead' + and r.date = (Select Max(r1.date) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.clinremarks r1 where r1.id = d1.id))) + + + + d3 on (d3.Id =d.id) + + + + --Handles NHPS with open Cases -LEFT JOIN ( + LEFT JOIN ( SELECT c.Id, - c.category, + c.category, c.assignedvet.DisplayName as vetNames, c.date - FROM study.cases c - WHERE (c.category not in ('Behavior','Surgery') - and c.IsOpen = 'true') - --and c.enddateCoalesced >= curdate() ) - --and c.allProblemCategories not like 'Routine%' - GROUP BY c.Id,c.category,c.date,c.assignedvet.DisplayName -) c ON (c.Id = d.Id) + FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.cases c + WHERE (c.category not in ('Behavior','Surgery') + and c.IsOpen= 'true') + --and c.enddateCoalesced >= curdate() ) + --and c.allProblemCategories not like 'Routine%' + GROUP BY c.Id,c.category,c.date,c.assignedvet.DisplayName + ) c ON (c.Id = d.Id) --Review for Assigned Animals -Left Join study.vet_AssignedResearch r1 on d.id = r1.id -Left Join study.vet_assignedResource r2 on d.id = r2.id --and r2.id not in (Select r3.id from study.vet_AssignedResearch r3) -Left Join study.housing h on h.id = d.id and (h.enddateTimeCoalesced >= now()) + left Join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.birth b on b.id = d.id + Left Join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.vet_AssignedResearch r1 on d.id = r1.id + Left Join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.vet_assignedResource r2 on d.id = r2.id --and r2.id not in (Select r3.id from study.vet_AssignedResearch r3) + Left Join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.housing h on h.id = d.id and (h.enddateTimeCoalesced >= now()) + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.deaths d1 on d.id = d1.id + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.departure d2 on d2.id = d.id + left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.demographics dm on dm.id = d.id + --left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.clinRemarks cr on cr.id = d.id + --report only on animals that are alive or deceased in last year where - (d.lastDayAtCenter is Null or d.lastDayAtCenter > TimeStampAdd('SQL_TSI_MONTH', -12,Now())) - --(d.calculated_Status = 'Alive' OR (d.death is null or d.death > TimeStampAdd('SQL_TSI_MONTH', -2,Now())) - and d.id not Like '[A-Z]%' \ No newline at end of file + (d2.date is Null or Cast(d2.date as varchar(20)) > d.MostRecentArrival or (d2.date > TimeStampAdd('SQL_TSI_MONTH', -12,Now()))) + and (d.demographics.calculated_status is not null) --and +-- d.id not Like '[A-Z]%' + and (d1.date < TimeStampAdd('SQL_TSI_DAY',-90,d1.date) or d1.date is Null) \ No newline at end of file diff --git a/onprc_ehr/resources/views/printableReports.html b/onprc_ehr/resources/views/printableReports.html index ceac1a872..485113efe 100644 --- a/onprc_ehr/resources/views/printableReports.html +++ b/onprc_ehr/resources/views/printableReports.html @@ -354,6 +354,74 @@ window.open(url); } },{ + html: '


    ', + style: 'padding-top: 10px;', + colspan: 4 + },{ + + html: 'Sustained Release Medications:' + + },{ + + style: 'padding-left: 60px;', + + + },{ + xtype: 'button', + style: 'margin-left: 5px;', + text: 'Print Version', + + border: true, + getUrlString: function(){ + var panel = this.up('#sheetPanel'); + var params = panel.getParams(true, true); + if (!params) + return; + + if (params.Rooms) + params.Rooms = params.Rooms.join(';'); + + + Ext4.apply(params, { + 'rs:ClearSession': true, + 'rs:Command': 'render' + }); + + var url = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSServerURL'); + var ssrsFolder = LABKEY.getModuleProperty('ONPRC_EHR', 'SSRSReportFolder'); + ssrsFolder = '/' + ssrsFolder + '/' + 'Clinical/ActiveTreatments_72hr'; + + url += ssrsFolder + '&' + LABKEY.ActionURL.queryString(params); + return url; + }, + menu: [{ + text: 'Print', + handler: function(menu){ + var btn = menu.up('button'); + var url = btn.getUrlString(); + if (!url) + return; + + window.open(url); + } + },{ + text: 'Print To PDF', + handler: function(menu){ + var btn = menu.up('button'); + var url = btn.getUrlString(); + if (!url) + return; + + url += '&rs:Format=PDF'; + window.open(url); + } + }] + + },{ + style: 'margin-left: 5px;', + + },{ + html: '
    ', style: 'padding-top: 10px;', colspan: 4 diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 3a903031a..96d3cb632 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -76,6 +76,7 @@ import org.labkey.onprc_ehr.history.DefaultAnimalGroupsEndDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalRecordFlagDataSource; import org.labkey.onprc_ehr.history.DefaultNHPTrainingDataSource; +import org.labkey.onprc_ehr.history.DefaultSustainedReleaseDatasource; import org.labkey.onprc_ehr.history.DefaultSnomedDataSource; import org.labkey.onprc_ehr.history.ONPRCClinicalRemarksDataSource; import org.labkey.onprc_ehr.history.ONPRCUrinalysisLabworkType; @@ -582,6 +583,12 @@ public String toString() //R.Blasa 11-28-2016 EHRService.get().registerHistoryDataSource(new DefaultNHPTrainingDataSource(this)); + + //R.Blasa 11-20-2019 + EHRService.get().registerHistoryDataSource(new DefaultSustainedReleaseDatasource(this)); + + + AdminLinkManager.getInstance().addListener((adminNavTree, container, user) -> { if (container.hasPermission(user, AdminPermission.class) && container.getActiveModules().contains(ONPRC_EHRModule.this)) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java index 5758bd470..c8ff5b16d 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BiopsyFormType.java @@ -23,9 +23,13 @@ import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.ehr.security.EHRPathologyEntryPermission; import org.labkey.api.module.Module; +import org.labkey.api.security.Group; +import org.labkey.api.security.GroupManager; import org.labkey.api.security.PrincipalType; import org.labkey.api.security.UserPrincipal; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; import java.util.Arrays; import java.util.HashMap; @@ -115,8 +119,20 @@ protected Integer getDefaultReviewRequiredPrincipal() UserPrincipal up = org.labkey.api.security.SecurityManager.getPrincipal(NecropsyFormType.DEFAULT_GROUP, getCtx().getContainer(), true); return up != null && up.getPrincipalType() == PrincipalType.GROUP ? up.getUserId() : null; } - + //Modified: 12-3-2019 R.Blasa @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "Pathology External Entry", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + + return super.isVisible(); + } + + @Override public JSONObject toJSON() { JSONObject ret = super.toJSON(); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java index 0b3606454..bd3b95dee 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java @@ -25,7 +25,11 @@ import org.labkey.api.ehr.security.EHRClinicalEntryPermission; import org.labkey.api.module.Module; import org.labkey.api.module.ModuleLoader; +import org.labkey.api.security.Group; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; import java.util.Arrays; @@ -68,4 +72,17 @@ protected boolean canInsert() return super.canInsert(); } + + //Modified: 12-5-2019 R.Blasa + @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "ASB Support", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + + return super.isVisible(); + } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/history/DefaultSustainedReleaseDatasource.java b/onprc_ehr/src/org/labkey/onprc_ehr/history/DefaultSustainedReleaseDatasource.java new file mode 100644 index 000000000..5c016bfcb --- /dev/null +++ b/onprc_ehr/src/org/labkey/onprc_ehr/history/DefaultSustainedReleaseDatasource.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016-2017 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.onprc_ehr.history; + +import org.apache.commons.lang3.StringUtils; +import org.labkey.api.data.Container; +import org.labkey.api.data.Results; +import org.labkey.api.module.Module; +import org.labkey.api.query.FieldKey; +import org.labkey.api.util.DateUtil; +import org.labkey.api.util.PageFlowUtil; +import org.labkey.onprc_ehr.ONPRC_EHRModule; + +import java.sql.Date; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Set; + +//Created: 11-20-2019 R.Blasa +public class DefaultSustainedReleaseDatasource extends AbstractEHRDataSource +{ + public DefaultSustainedReleaseDatasource(Module module) + { + super("study", "DrugsGiven72hours", "Clinical Sustained Release Medication", "Clinical", module); + } + + @Override + protected String getHtml(Container c, Results rs, boolean redacted) throws SQLException + { + + + String end = rs.getString(FieldKey.fromString("enddate")); + String start = rs.getString(FieldKey.fromString("date")); + + + StringBuilder sb = new StringBuilder(); + + + sb.append("Starting Date: ").append(start); + sb.append("\n"); + + + if (rs.getObject(FieldKey.fromString("enddate")) != null) + { + sb.append("Ending Date: ").append(end); + sb.append("\n"); + } +// sb.append(safeAppend(rs, "Starting Date: ", "start")); +// sb.append(safeAppend(rs, "Ending Date:", "end")); + sb.append(safeAppend(rs, "Category", "category")); + sb.append(safeAppend(rs, "Medicaion", "meaning")); + sb.append(safeAppend(rs, "Medication Code", "code")); + sb.append(safeAppend(rs, "Amount/Volume", "amountAndVolume")); + sb.append(safeAppend(rs, "Route", "route")); + sb.append(safeAppend(rs, "Elapased Hours", "ElapseHours")); + sb.append(safeAppend(rs, "Remarks", "remark")); + + + return sb.toString(); + } + + @Override + protected Set getColumnNames() + { + + return PageFlowUtil.set("Id", "date", "enddate", "catgory", "meaning","route", "code","amountAndVolume","ElapseHours", "remark"); + } +} From 3d12fe6e725bb607facb113088fcb3088ba0d90b Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 19:25:39 -0700 Subject: [PATCH 09/49] Merge from onprc19.1 r.64939 to 64951 --- .../LeaseFeeDefinitionUnitCost.sql | 22 +++ .../LeaseFeeReleaseAdjustment.sql | 30 ++-- .../onprc_billing/LeaseFee_Demographics.sql | 27 ++-- .../onprc_billing/LeaseFee_LeaseType.sql | 20 ++- .../onprc_billing/LeaseFee_UnitCostCalc.sql | 71 +++++++++ .../LeaseFee_UnitCostCalc_DataSource.sql | 37 +++++ .../LeaseFee_UnitCost_RateCalc.sql | 73 +++++++++ .../onprc_billing/assignment_U42ESPF.sql | 8 + .../onprc_billing/leaseFeeRates_2020.sql | 122 +++++++++++++++ .../onprc_billing/leasefee_rateData.sql | 33 ++-- .../onprc_billing/leasefee_rateFunction.sql | 29 ++++ .../onprc_billing/miscChargesWithRates.sql | 32 ++-- .../queries/study/DrugsGiven72hours.sql | 4 +- .../resources/views/IndustrialRatesCalc.html | 146 ++++++++++++++++++ .../views/IndustrialRatesCalc.view.xml | 6 + .../views/IndustrialRatesCalc.webpart.xml | 6 + .../views/NIHPublicFinanceRates.view.xml | 6 + .../views/NIHPublicFinanceRates.webpart.xml | 6 + onprc_ehr/resources/views/NIHRateSheet.html | 31 ++++ .../resources/views/NIHRateSheet.view.xml | 6 + .../resources/views/NIHRateSheet.webpart.xml | 6 + .../resources/views/NIHReducedRates.html | 65 ++++++++ .../resources/views/NIHReducedRates.view.xml | 6 + .../views/NIHReducedRates.webpart.xml | 6 + 24 files changed, 747 insertions(+), 51 deletions(-) create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFeeDefinitionUnitCost.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc_DataSource.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCost_RateCalc.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/assignment_U42ESPF.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leasefee_rateFunction.sql create mode 100644 onprc_ehr/resources/views/IndustrialRatesCalc.html create mode 100644 onprc_ehr/resources/views/IndustrialRatesCalc.view.xml create mode 100644 onprc_ehr/resources/views/IndustrialRatesCalc.webpart.xml create mode 100644 onprc_ehr/resources/views/NIHPublicFinanceRates.view.xml create mode 100644 onprc_ehr/resources/views/NIHPublicFinanceRates.webpart.xml create mode 100644 onprc_ehr/resources/views/NIHRateSheet.html create mode 100644 onprc_ehr/resources/views/NIHRateSheet.view.xml create mode 100644 onprc_ehr/resources/views/NIHRateSheet.webpart.xml create mode 100644 onprc_ehr/resources/views/NIHReducedRates.html create mode 100644 onprc_ehr/resources/views/NIHReducedRates.view.xml create mode 100644 onprc_ehr/resources/views/NIHReducedRates.webpart.xml diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeDefinitionUnitCost.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeDefinitionUnitCost.sql new file mode 100644 index 000000000..405a9f349 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeDefinitionUnitCost.sql @@ -0,0 +1,22 @@ +PARAMETERS(chargeDate TIMESTAMP DEFAULT '1/1/2019') + +SELECT lf.rowId, +--lf.minAge, +--lf.maxAge, +--lf.assignCondition, +--lf.releaseCondition, +lf.chargeId, +lf.chargeid.rowId as lfRowID, +cr.chargeid.rowid as CRRowID, +cr.unitcost, +lf.chargeunit, +lf.active, +lf.startDate as lfstartdate, +cr.startDate as CRStartdate, +lf.endDate as lfenddate, +cr.enddate as crEndDate +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRates cr + on lf.chargeID.rowid = cr.chargeID.rowid --and lf.startdate >= cr.startDate and lf.enddate <= cr.enddate) +where ((lf.startdate <= chargedate and lf.enddate >= chargedate) + and (cr.startdate <=Chargedate and cr.enddate >= chargedate)) \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql index cf3bd27c0..05f0de6da 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql @@ -1,3 +1,4 @@ +--Update to full path Source PARAMETERS (StartDate TIMESTAMP, EndDate TIMESTAMP) SELECT @@ -8,7 +9,13 @@ case End as date, --a.date, a.project, -a.account as alias, +a.project.project as projectID, +a.project.account as alias, +a.project.account.farate as faRate, +a.project.account.aliastype.removesubsidy as removeSubsidy, +a.project.account.aliastype.canRaiseFA as CanRaiseFA, +a.project.account.investigatorID, +a.project.account.fiscalAuthorityName as FANAme, a.date as assignmentStart, a.enddate, a.projectedReleaseCondition, @@ -19,7 +26,7 @@ a.ageAtTime.AgeAtTimeYearsRounded as ageAtTime, a5.id as ESPFAnimal, 'Lease Fees' as category, --////This selectes the charge ID to be used -(SELECT max(rowid) as rowid FROM onprc_billing_public.chargeableItems ci WHERE ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.LEASE_FEE_ADJUSTMENT') and ci.active = true) as chargeId, +(SELECT max(rowid) as rowid FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.chargeableItems ci WHERE ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.LEASE_FEE_ADJUSTMENT') and ci.active = true) as chargeId, CASE when (fl.id Is Not Null) then 0 else 1 @@ -32,8 +39,9 @@ a.objectid as sourceRecord, a.datefinalized, a.enddatefinalized -FROM "/onprc/ehr".study.assignment a -LEFT JOIN "/ONPRC/Admin/Finance".onprc_billing.leaseFeeDefinition lf + +FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON (lf.assignCondition = a.assignCondition AND lf.releaseCondition = a.releaseCondition AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf.minAge OR lf.minAge IS NULL) @@ -42,7 +50,7 @@ LEFT JOIN "/ONPRC/Admin/Finance".onprc_billing.leaseFeeDefinition lf and a.date <= lf.endDate) ) -LEFT JOIN "/ONPRC/Admin/Finance".onprc_billing.leaseFeeDefinition lf2 +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf2 ON (lf2.assignCondition = a.assignCondition AND lf2.releaseCondition = a.projectedReleaseCondition AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf2.minAge OR lf2.minAge IS NULL) @@ -52,23 +60,23 @@ LEFT JOIN "/ONPRC/Admin/Finance".onprc_billing.leaseFeeDefinition lf2 ) --find overlapping TMB at date of assignment - LEFT JOIN "/onprc/ehr".study.assignment a2 ON ( + LEFT JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 ON ( a.id = a2.id AND a.project != a2.project AND a2.dateOnly <= a.dateOnly AND a2.endDateCoalesced >= a.dateOnly AND a2.project.name = javaConstant('org.labkey.onprc_ehr.ONPRC_EHRManager.TMB_PROJECT') ) -LEFt join onprc_billing.assignment_U42ESPF a5 on +LEFt join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.assignment_U42ESPF a5 on ( a.id = a5.id and a.project !=a5.project and a5.project = 1107 and a5.dateonly <=a.dateOnly AND a5.endDateCoalesced >= a.dateOnly) --adds the reasearch owned animal exemption -Left JOIN "/onprc/ehr".study.flags fl on - (a.id = fl.id - and fl.flag.code = 4034 - and (a.date >= fl.date and a.date <=COALESCE(fl.enddate,Now()) )) +Left JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.flags fl on + (a.id = fl.id + and fl.flag.code = 4034 + and (a.date >= fl.date and a.date <=COALESCE(fl.enddate,Now()) )) WHERE a.releaseCondition != a.projectedReleaseCondition and (A.id != A5.id or A5.id is Null) diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql index bd241705f..642b3b85f 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql @@ -6,15 +6,17 @@ PI Purchased NHP is code in studyflags to look for Need to determine if this is a day lease Add Column for Credit To Lease Type - Reqds from the query for leases and populates the lease sequnce to use -??Is there a benefit to having a query that reads lease charges from the +??Is there a benefit to having a query that reads lease charges from the\ +Update of File 2020-01-10 insured that all files use the subsistue page */ +--Update to resolve path issues PARAMETERS(StartDate TIMESTAMP, EndDate TIMESTAMP) SELECT distinct a.Id, Case - When a.id in (Select f.id from study.flags f where (f.id = a.id and f.flag.value = 'PI Purchased NHP' and f.enddate is Null)) then 'yes' + When a.id in (Select f.id from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.flags f where (f.id = a.id and f.flag.value = 'PI Purchased NHP' and f.enddate is Null)) then 'yes' else 'No' -End as ResearchOwned, + End as ResearchOwned, a.project, a.project.account as ProjectAlias, @@ -61,8 +63,8 @@ Case --need to determine if this is a dual assignment so we can tag who receives the credit Case - when (Select Count(a2.project.name) from study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) > 2 then 'Over 2 Assignments' - when (Select Count(a2.project.name) from study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) = 2 then + when (Select Count(a2.project.name) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) > 2 then 'Over 2 Assignments' + when (Select Count(a2.project.name) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) = 2 then 'Dual Assigned' End as MultipleAssignments, @@ -71,6 +73,7 @@ End as MultipleAssignments, a.date, +a.project.project as projectID, a.projectedRelease, a.enddate, a.datefinalized, @@ -79,7 +82,11 @@ a.projectedReleaseCondition, a.releaseCondition, a.releaseType, a.remark, -a.project.account As alias +a.project.account As alias, +a.project.account.farate, +a.project.account.aliasType.removesubsidy, +a.project.account.aliasType.canRaiseFA + --This looks at situations where an animal is being dual assigned and credits the correct resource --Case @@ -89,9 +96,9 @@ a.project.account As alias --End as CreditTo, -FROM study.assignment a -left outer join study.tmbBirth t on a.id = t.id -left join study.birth_resourceDam d on a.id = d.id +FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a +left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.tmbBirth t on a.id = t.id +left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.birth_resourceDam d on a.id = d.id --left outer join study.tmbdam t on t.id = a.id.birth.dam -where a.date >= startDate and (a.date <= enddate or a.enddate is null) +where a.datefinalized >= startDate and (a.datefinalized <= enddate or a.enddate is null) and a.id not like '[a-z]%' \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql index 5cb1caf69..856b560f6 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql @@ -14,7 +14,7 @@ COndition Code Change 00Not if PI Owned] Not if ESPF one use Animal Obese - TMB - ESPF - +--Update 2020-01-10 Changes ESPF to U42 Expanded SPF Lease so that will properly display */ SELECT @@ -36,7 +36,7 @@ Case When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition != l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null) then 'Day Lease Research Assignment P51 NHP Condition Change' --Dual assigned ESPF using different Chared Code - When da.project.Name = '0492-03' then 'DualAssignedESPF' + When da.project.Name = '0492-03' then 'U42 Expanded SPF Lease' --Dual assigned TMB Male on Day Lease When l.agegroup = 'Adult' and da.project.name = '0300' and l.dayLease = 'yes' then 'TMB Adult Day Lease' @@ -72,7 +72,7 @@ Case -- when (Select l2.DayLeaseConditionChange from study.lease_DayLeaseAdult l2 where l2.id = l.id) = 'No' and l.dayLease = 'yes' Then 'Adult Day Lease No Condition Change' /*********Dual Assigned ESPFTMB Birth */ - When da.project.Name = '0492-03' then 'DualAssignedESPF' + When da.project.Name = '0492-03' then 'U42 Expanded SPF Lease' ----Dual Assigned Obese JMac Infant or Dam Day Lease = No condition Code CHanges - if change full lease --need to change to also incldue if the damn is there When da.project.name = '0622-01' and l.daylease = 'yes' then 'Obese 0622-01 Day Lease' @@ -153,10 +153,14 @@ l.projectedReleaseCondition, l.releaseCondition, l.releaseType, l.remark, -l.alias -FROM onprc_billing.leasefee_demographics l - left outer join study.birth b on l.id = b.id - left outer join study.lease_ObeseInfant_HFDDam R on l.id = r.id - Left outer join study.dualassigned da on da.id = l.id and (da.dualassignment = l.project +l.alias, +l.faRate, +l.removesubsidy, +l.canRaiseFA, +l.project.project as projectID +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_demographics l + left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.birth b on l.id = b.id + left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.lease_ObeseInfant_HFDDam R on l.id = r.id + Left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.dualassigned da on da.id = l.id and (da.dualassignment = l.project and (da.enddate is null or da.enddate > l.date) and (da.dualenddate is null or Dualenddate > l.date)) where l.researchowned = 'no' \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc.sql new file mode 100644 index 000000000..e1bbfdfd6 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc.sql @@ -0,0 +1,71 @@ +SELECT d.Id, + r.leasetype, + d.ResearchOwned, + d.project, --integer + d.ProjectAlias, + d.AgeAtAssignment, + d.ageinyears, + d.AgeGroup, + d.BirthAssignment, + d.BirthType, + d.AssignmentType, + d.DayLease, + d.DayLeaseLength, --integer + d.MultipleAssignments, + d.date, + d.projectedRelease, + d.enddate, + d.datefinalized, + d.assignCondition, --integer + d.projectedReleaseCondition, --integer + d.releaseCondition, --integer + d.releaseType, + d.remark, + d.alias, + d.farate, + d.removesubsidy, + d.canRaiseFA, + r.ChargeID, --integer + RateCalc(d.alias,r.chargeID,d.project,d.Date,d.farate) as CalculatedRate, + r.revisedChargeID + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateData r join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project + + +union + +select + a.id, + 'automatic_adjustment' as AssignmentType, + '' as researchOwned, + a.projectID, --intege + a.alias, + a.ageattime, + 1 as ageinYears, --need to run function to return years + '' as agegroup, + '' as BirthAssignment, + '' as BirthType, + 'automatic_adjustment' as AssignmentTypeNA, + '' as DayLease, + '' as DayLeaseLength, --integer + '' as MultipleAssignments, + a.date, + a.enddate as projectedrelease, + a.enddate, + a.datefinalized, + a.assignCondition, --0integer + a.projectedReleaseCondition, --integer + a.releaseCondition,--integer + a.releasetype, + '' as remark, + a.alias as alias2, + a.faRate as farate, + a.removeSubsidy as removesubsidy, + a.canRaiseFA as canRaiseFA, + a.leaseCharge1, --integer + ' ' as CalculatedRate, + a.leaseCharge2 + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFeeReleaseAdjustment a \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc_DataSource.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc_DataSource.sql new file mode 100644 index 000000000..4a2cd51a1 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCostCalc_DataSource.sql @@ -0,0 +1,37 @@ +SELECT d.Id, + d.datefinalized as date, + r.CenetrProject as project, + r.alias as account, + t.ReleaseDate as enddate, + r.ProjectedReleaseCondition as ProjectedReleaseCondition, + d.releasecondition, + d.assignCondition as assigncondition, + d.releaseType, + d.AgeAtAssignment as AgeAtTime, + d.ageinyears, + d.AgeGroup, + d.BirthAssignment, + d.BirthType, + d.AssignmentType, + d.DayLease, + d.DayLeaseLength, + d.MultipleAssignments, + d.date, + d.projectedRelease, + d.enddate, + d.datefinalized as dateFinalized, + d.remark as comment, + d.farate, + d.removesubsidy, + d.canRaiseFA, + r.chargeID as LeaseCharge1, --original lease type + r.RevisedChargeID as LeaseCharge2, --Final Leases Type + t.creditto as CreditAccount + + +from onprc_billing.leaseFee_demographics d + -- Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project + Join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateData r on r.id = d.id and r.projectID = d.project and r.assignmentDate = d.date + +\\\ \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCost_RateCalc.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCost_RateCalc.sql new file mode 100644 index 000000000..7958e085b --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_UnitCost_RateCalc.sql @@ -0,0 +1,73 @@ +--Corrested Issue with Adjustments and loading into Test + +SELECT d.Id, + r.leasetype, + d.ResearchOwned, + d.project, --integer + d.ProjectAlias, + d.AgeAtAssignment, + d.ageinyears, + d.AgeGroup, + d.BirthAssignment, + d.BirthType, + d.AssignmentType, + d.DayLease, + d.DayLeaseLength, --integer + d.MultipleAssignments, + d.date, + d.projectedRelease, + d.enddate, + d.datefinalized, + d.assignCondition, --integer + d.projectedReleaseCondition, --integer + d.releaseCondition, --integer + d.releaseType, + d.remark, + d.alias, + d.farate, + d.removesubsidy, + d.canRaiseFA, + r.ChargeID, --integer + RateCalc(d.alias,r.chargeID,d.project,d.Date,d.farate) as CalculatedRate, + r.revisedChargeID + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateData r join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project + + +union + +select + a.id, + 'automatic_adjustment' as AssignmentType, + '' as researchOwned, + a.projectID, --intege + a.alias, + a.ageattime, + 1 as ageinYears, --need to run function to return years + '' as agegroup, + '' as BirthAssignment, + '' as BirthType, + 'automatic_adjustment' as AssignmentTypeNA, + '' as DayLease, + '' as DayLeaseLength, --integer + '' as MultipleAssignments, + a.date, + a.enddate as projectedrelease, + a.enddate, + a.datefinalized, + a.assignCondition, --0integer + a.projectedReleaseCondition, --integer + a.releaseCondition,--integer + a.releasetype, + '' as remark, + a.alias as alias2, + a.faRate as farate, + a.removeSubsidy as removesubsidy, + a.canRaiseFA as canRaiseFA, + a.leaseCharge1, --integer + RateCalc(a.alias,a.leasecharge2,a.projectID, a.date,a.farate) as RevisedRate, + a.leaseCharge2 + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFeeReleaseAdjustment a \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/assignment_U42ESPF.sql b/onprc_billing/resources/queries/onprc_billing/assignment_U42ESPF.sql new file mode 100644 index 000000000..2666909cd --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/assignment_U42ESPF.sql @@ -0,0 +1,8 @@ + +SELECT a.Id, +a.project, +a.project.use_category, +a.dateOnly, +a.endDateCoalesced +FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a +where a.enddate is Null and a.project.use_category like '%ESPF%' \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql new file mode 100644 index 000000000..a2f3646d4 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql @@ -0,0 +1,122 @@ +--Corrested Issue with Adjustments and loading into Test + +SELECT d.Id, + r.leasetype, + d.ResearchOwned, + d.project, --integer + d.ProjectAlias, + d.AgeAtAssignment, + d.ageinyears, + d.AgeGroup, + d.BirthAssignment, + d.BirthType, + d.AssignmentType, + d.DayLease, + d.DayLeaseLength, --integer + d.MultipleAssignments, + d.date, + d.projectedRelease, + d.enddate, + d.datefinalized, + d.assignCondition, --integer + d.projectedReleaseCondition, --integer + d.releaseCondition, --integer + d.releaseType, + d.remark, + d.alias, + d.farate, + d.removesubsidy, + d.canRaiseFA, + r.ChargeID, --integer + i.Name as Item, + i.DepartmentCode as ServiceCenter, + RateCalc(d.alias,r.chargeID,d.project,d.Date,d.farate) as CalculatedRate, + r.revisedChargeID + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateData r join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeableItems i on i.rowID = r.chargeID + +union + +select + a.id, + 'automatic_adjustment' as AssignmentType, + '' as researchOwned, + a.projectID, --intege + a.alias, + a.ageattime, + 1 as ageinYears, --need to run function to return years + '' as agegroup, + '' as BirthAssignment, + '' as BirthType, + 'automatic_adjustment' as AssignmentTypeNA, + '' as DayLease, + '' as DayLeaseLength, --integer + '' as MultipleAssignments, + a.date, + a.enddate as projectedrelease, + a.enddate, + a.datefinalized, + a.assignCondition, --0integer + a.projectedReleaseCondition, --integer + a.releaseCondition,--integer + a.releasetype, + '' as remark, + a.alias as alias2, + a.faRate as farate, + a.removeSubsidy as removesubsidy, + a.canRaiseFA as canRaiseFA, + a.leaseCharge1, --integer + ii.name as Item, + ii.DepartmentCode as ServiceCenter, + RateCalc(a.alias,a.leasecharge2,a.projectID, a.date,a.farate) as RevisedRate, + a.leaseCharge2 + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFeeReleaseAdjustment a +join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeableItems ii on ii.rowID = a.chargeID + + +Union + + +Select + r.id, + 'Misc Charge', + null as researchOwned, + r.project, + r.account.alias, + null as ageatTime, + null as ageInYears, + null as AgeGroup, + null as BirthAssignment, + null as BirthType, + 'Misc Charge' as AssignmentTypeNA, + null as DayLease, + null as DayLeaseLength, --integer + null as MultipleAssignments, + r.date, + null as projectedrelease, + null as enddate, + null as datefinalized, + null as assignCondition, --0integer + null as projectedReleaseCondition, --integer + null as releaseCondition,--integer + null as releasetype, + r.comment as remark, + null as alias2, + null as farate, + null as removesubsidy, + null as canRaiseFA, + r.chargeID, --integer + r.chargeID.Name as Item, + r.serviceCenter as ServiceCenter, + r.rateCalc, + null as rate2 + + + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.miscChargesWithRates r +WHERE cast(r.billingDate as date) >= CAST(StartDate as date) AND cast(r.billingDate as date) <= CAST(EndDate as date) +AND r.category IN ('Lease Fees', 'Lease Setup Fee', 'Lease Setup Fees') diff --git a/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql b/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql index 361d565f1..5b42b3f1c 100644 --- a/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql +++ b/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql @@ -1,8 +1,11 @@ --this returns day lease for adults --updated 6/7/2019 correction of previous lease lookup +--2020-01-10 Updae to change the ESPF top correct Value +-- resolved issue to insura all data sources use Subsstitute Path Select l.id, l.project.name as CenterProject, +l.project.project as ProjectID, l.alias, l.leasetype, l.assignmentdate, @@ -19,11 +22,12 @@ l.dayleaselength as quantity -FROM onprc_Billing.leaseFee_LeaseType l JOIN onprc_billing.leaseFeeDefinition lf ON ( +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l + JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( l.Leasetype = lf.chargeId.Name AND lf.active = true) -where l.daylease <> 'yes' +where l.daylease <> 'yes' and l.leasetype != 'U42 Expanded SPF Lease' UNION @@ -31,6 +35,7 @@ UNION Select l.id, l.project.name as CenterProject, +l.project.project as ProjectID, l.alias, l.leasetype, l.assignmentdate, @@ -38,7 +43,7 @@ l.assignCondition.code, l.projectedReleaseCondition.code as ProjectedReleaseCode, Cast(l.ageAtAssignment as Integer) as AssignmentAge, Case - When l.leasetype = 'U42 Expanded SPF Lease' then lf.chargeId + When l.leasetype = 'U42 Expanded SPF Lease' then lf.chargeID else Null End as chargeId, Null as RevisedChargeID, @@ -46,7 +51,8 @@ Null as RevisedChargeID, -FROM onprc_Billing.leaseFee_LeaseType l JOIN onprc_billing.leaseFeeDefinition lf ON ( +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l JOIN + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( l.Leasetype = lf.chargeId.Name AND lf.active = true) @@ -58,6 +64,7 @@ UNION SELECT l.id, l.project.name as CenterProject, +l.project.project as ProjectID, l.alias, l.leasetype, l.assignmentdate, @@ -70,7 +77,8 @@ Null as RevisedChargeID, 1 as quantity -FROM onprc_Billing.leaseFee_LeaseType l left outer JOIN onprc_billing.leaseFeeDefinition lf ON ( +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l + left outer JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( lf.assignCondition = l.assignCondition.code AND lf.releaseCondition = l.projectedReleaseCondition.code @@ -86,6 +94,7 @@ UNION --day lease no condition change SELECT l.id, l.project.name as CenterProject, +l.project.project as ProjectID, l.alias, l.leasetype, l.assignmentdate, @@ -99,7 +108,7 @@ end as ChargeID, Null as RevisedChargeID, l.dayleaselength as Quantity -FROM onprc_Billing.leaseFee_LeaseType l +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l where l.daylease = 'yes' and l.leasetype <> 'Day Lease Research Assignment P51 NHP Condition Change' UNION @@ -108,6 +117,7 @@ UNION --day lease condition change SELECT l.id, l.project.name as CenterProject, +l.project.project as ProjectID, l.alias, l.leasetype, l.assignmentdate, @@ -120,8 +130,8 @@ Null as RevisedChargeID, 1 as Quantity -FROM onprc_Billing.leaseFee_LeaseType l - left outer JOIN onprc_billing.leaseFeeDefinition lf ON ( +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l + left outer JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( lf.assignCondition = l.assignCondition.code AND lf.releaseCondition = l.ReleaseCondition.code @@ -136,6 +146,7 @@ UNION SELECT l.id, l.project.name as CenterProject, +l.project.project as ProjectID, l.alias, l.leasetype, l.assignmentdate, @@ -150,7 +161,8 @@ Null as RevisedChargeID, 1 as quantity -FROM onprc_Billing.leaseFee_LeaseType l left outer JOIN onprc_billing.leaseFeeDefinition lf ON ( +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l + left outer JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( lf.assignCondition = l.assignCondition.code AND lf.releaseCondition = l.projectedReleaseCondition.code @@ -166,6 +178,7 @@ UNION Select r.id, r.project.name as CenterProject, +r.project.project as ProjectID, r.alias, 'Adjustment-Automatic' as LeaseType, r.date, @@ -178,4 +191,4 @@ r.leasecharge1 as revisedChargeID, 1 as quantity -from onprc_billing.leaseFeeReleaseAdjustment r \ No newline at end of file +from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeReleaseAdjustment r \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/leasefee_rateFunction.sql b/onprc_billing/resources/queries/onprc_billing/leasefee_rateFunction.sql new file mode 100644 index 000000000..af90ffd4b --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/leasefee_rateFunction.sql @@ -0,0 +1,29 @@ +--PARAMETERS(A VARCHAR DEFAULT '9012221',P double DEFAULT 277, +-- c DOUBLE DEFAULT 1477, +-- s TIMESTAMP DEFAULT '1/1/2019', +-- B DOUBLE +-- ) +--2019-11-22 clean up of code onn function had a bad date select +Select +c.id, +c.CenterProject, +c.alias, +c.alias as ChargeTO, +t.creditTo, +c.projectID, +c.chargeId, +t.leasetype, +r.unitcost, +c.assignmentDate, +t.faRate, +t.removesubsidy, +t.canRaiseFA, + +RateCalc(c.alias,c.chargeID,c.projectID,c.assignmentDate,t.farate) as CalculatedRate + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leasefee_RateData c + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates r + on c.chargeID = r.chargeID + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leasefee_leaseType t + on (c.id = t.id and c.projectID = t.projectID and t.assignmentDate = c.assignmentDate) +where r.startDate <= c.assignmentDate and r.enddate >= c.assignmentDate \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql index cd6d17fd6..5ab13fd93 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql @@ -1,3 +1,4 @@ +--Udpate 20200107 using fiull path for source SELECT p.Id, p.date, @@ -8,6 +9,17 @@ SELECT p.chargeId, COALESCE(p.chargetype.servicecenter, p.chargeId.departmentCode) as serviceCenter, coalesce(p.chargeId.name, p.item) as item, + p.unitCost as MCEnteredUnitCost, + case + WHen p.unitCost is NOT NULL then p.unitCost + When RateCalc(p.debitedaccount,p.chargeID,p.project,p.Date,alias.farate) Is Not Null then RateCalc(p.debitedaccount,p.chargeID,p.project,p.Date,alias.farate) + Else cr.unitcost + ENd as RateCalc, + case + WHen p.unitCost is NOT NULL then 'Misc Rate Entered' + When RateCalc(p.debitedaccount,p.chargeID,p.project,p.Date,alias.farate) Is Not Null then 'Rate Calc Function' + else 'Passed Thru to Cr UnitCost' + ENd as RateMethod, round(CAST(CASE --order of priority for unit cost: --if this row specifies a unit cost, like an adjustment, defer to that. this is unique to miscCharges @@ -80,7 +92,7 @@ SELECT WHEN (p.project IS NULL AND p.debitedaccount IS NOT NULL) THEN null --note: allow charges entered by account only WHEN p.project IS NULL THEN 'N' WHEN p.project.alwaysavailable = true THEN null - WHEN (SELECT count(*) as projects FROM study.assignment a WHERE + WHEN (SELECT count(*) as projects FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a WHERE p.Id = a.Id AND (p.project = a.project OR p.project.protocol = a.project.protocol) AND (cast(p.date AS DATE) <= a.enddateCoalesced OR a.enddate IS NULL) AND @@ -88,7 +100,7 @@ SELECT ) > 0 THEN null ELSE 'N' END as matchesProject, - (SELECT group_concat(distinct a.project.displayName, chr(10)) as projects FROM study.assignment a WHERE + (SELECT group_concat(distinct a.project.displayName, chr(10)) as projects FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a WHERE p.Id = a.Id AND (cast(p.date AS DATE) <= a.enddateCoalesced OR a.enddate IS NULL) AND cast(p.date as date) >= a.dateOnly @@ -117,44 +129,44 @@ SELECT END as accountDiffersFromProject, true as isMiscCharge -FROM onprc_billing.miscCharges p +FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.onprc_billing.miscCharges p -LEFT JOIN onprc_billing_public.chargeRates cr ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.chargeRates cr ON ( CAST(p.date AS DATE) >= CAST(cr.startDate AS DATE) AND (CAST(p.date AS DATE) <= cr.enddateCoalesced OR cr.enddate IS NULL) AND p.chargeId = cr.chargeId ) -LEFT JOIN onprc_billing_public.chargeRateExemptions e ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.chargeRateExemptions e ON ( CAST(p.date AS DATE) >= CAST(e.startDate AS DATE) AND (CAST(p.date AS DATE) <= e.enddateCoalesced OR e.enddate IS NULL) AND p.chargeId = e.chargeId AND p.project = e.project ) -LEFT JOIN onprc_billing_public.creditAccount ce ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.creditAccount ce ON ( CAST(p.date AS DATE) >= CAST(ce.startDate AS DATE) AND (CAST(p.date AS DATE) <= ce.enddateCoalesced OR ce.enddate IS NULL) AND p.chargeId = ce.chargeId ) -LEFT JOIN onprc_billing_public.projectAccountHistory aliasAtTime ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.projectAccountHistory aliasAtTime ON ( aliasAtTime.project = p.project AND aliasAtTime.startDate <= cast(p.date as date) AND aliasAtTime.endDate >= cast(p.date as date) ) -LEFT JOIN onprc_billing_public.aliases alias ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.aliases alias ON ( alias.alias = COALESCE(p.debitedaccount, aliasAtTime.account) ) -LEFT JOIN onprc_billing_public.projectMultipliers pm ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.projectMultipliers pm ON ( CAST(p.date AS DATE) >= CASt(pm.startDate AS DATE) AND (CAST(p.date AS DATE) <= pm.enddateCoalesced OR pm.enddate IS NULL) AND alias.alias = pm.account ) -LEFT JOIN onprc_billing_public.chargeUnitAccounts cu ON ( +LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.chargeUnitAccounts cu ON ( p.chargetype = cu.chargetype AND cast(cu.startDate AS date) <= cast(p.date as date) AND cast(cu.endDate AS date) >= cast(p.date as date) diff --git a/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql b/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql index f9877b019..1d26c7b65 100644 --- a/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql +++ b/onprc_ehr/resources/queries/study/DrugsGiven72hours.sql @@ -31,7 +31,7 @@ SELECT FROM study.drug p WHERE p.qcstate.publicdata = true and timestampdiff('SQL_TSI_HOUR',p.date, now() ) < 73 -and p.code = 'E-Y9723' +and p.code in (select code from ehr_lookups.snomed_subset_codes Where primaryCategory = 'Sustained Medications' ) and p.route <> 'Spillage' UNION @@ -51,5 +51,5 @@ SELECT FROM study.treatment_order s WHERE s.qcstate.publicdata = true and timestampdiff('SQL_TSI_HOUR',s.date, now() ) < 73 -and s.code = 'E-Y9723' +and s.code in (select code from ehr_lookups.snomed_subset_codes Where primaryCategory = 'Sustained Medications' ) and s.route <> 'Spillage' diff --git a/onprc_ehr/resources/views/IndustrialRatesCalc.html b/onprc_ehr/resources/views/IndustrialRatesCalc.html new file mode 100644 index 000000000..f9cddde69 --- /dev/null +++ b/onprc_ehr/resources/views/IndustrialRatesCalc.html @@ -0,0 +1,146 @@ + + + + + NIH Industrial Rates + + + + + +

    Industrial Rates

    +
    +
    + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml b/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml new file mode 100644 index 000000000..eeed2e4dd --- /dev/null +++ b/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/IndustrialRatesCalc.webpart.xml b/onprc_ehr/resources/views/IndustrialRatesCalc.webpart.xml new file mode 100644 index 000000000..0affac058 --- /dev/null +++ b/onprc_ehr/resources/views/IndustrialRatesCalc.webpart.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHPublicFinanceRates.view.xml b/onprc_ehr/resources/views/NIHPublicFinanceRates.view.xml new file mode 100644 index 000000000..e26bbfb22 --- /dev/null +++ b/onprc_ehr/resources/views/NIHPublicFinanceRates.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHPublicFinanceRates.webpart.xml b/onprc_ehr/resources/views/NIHPublicFinanceRates.webpart.xml new file mode 100644 index 000000000..cb63ba539 --- /dev/null +++ b/onprc_ehr/resources/views/NIHPublicFinanceRates.webpart.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHRateSheet.html b/onprc_ehr/resources/views/NIHRateSheet.html new file mode 100644 index 000000000..a2931a09b --- /dev/null +++ b/onprc_ehr/resources/views/NIHRateSheet.html @@ -0,0 +1,31 @@ + + + + + NIHRateSheet + + + +
    + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHRateSheet.view.xml b/onprc_ehr/resources/views/NIHRateSheet.view.xml new file mode 100644 index 000000000..6c0266393 --- /dev/null +++ b/onprc_ehr/resources/views/NIHRateSheet.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHRateSheet.webpart.xml b/onprc_ehr/resources/views/NIHRateSheet.webpart.xml new file mode 100644 index 000000000..a80f61181 --- /dev/null +++ b/onprc_ehr/resources/views/NIHRateSheet.webpart.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHReducedRates.html b/onprc_ehr/resources/views/NIHReducedRates.html new file mode 100644 index 000000000..2ccc082ff --- /dev/null +++ b/onprc_ehr/resources/views/NIHReducedRates.html @@ -0,0 +1,65 @@ + + + + + NIHReducedRates + + + + +

    Reduced F&A Rate Sheet

    +
    +
    + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHReducedRates.view.xml b/onprc_ehr/resources/views/NIHReducedRates.view.xml new file mode 100644 index 000000000..cdc69019e --- /dev/null +++ b/onprc_ehr/resources/views/NIHReducedRates.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/NIHReducedRates.webpart.xml b/onprc_ehr/resources/views/NIHReducedRates.webpart.xml new file mode 100644 index 000000000..3f1a7abe1 --- /dev/null +++ b/onprc_ehr/resources/views/NIHReducedRates.webpart.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 383326c83bd4596827bb34aa2ce5df8fdd1af025 Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 19:36:41 -0700 Subject: [PATCH 10/49] Merge from onprc19.1 r.64953 to 65052 --- extscheduler/resources/views/weeklyTest.html | 2 +- .../onprc_billing/LeaseFeeRates_Final.sql | 91 +++++++++ .../onprc_billing/LeaseFee_Demographics.sql | 16 +- .../onprc_billing/LeaseFee_LeaseType.sql | 70 +++---- .../onprc_billing/invoiceditems.query.xml | 2 +- .../onprc_billing/leaseFeeRates_2020.sql | 48 ++++- .../onprc_billing/leaseFee_RateReview.sql | 95 +++++---- .../onprc_billing/leaseFee_RateReview_org.sql | 65 +++++++ .../onprc_billing/leasefee_rateChargeItem.sql | 34 ++++ .../onprc_billing/leasefee_rateData.sql | 22 +++ .../miscChargesNotBilled_Virology.query.xml | 2 +- .../perDiemFeeDefinition.query.xml | 2 +- .../resources/schemas/onprc_billing.xml | 2 +- .../resources/queries/ehr/requests.query.xml | 20 +- .../vet_assignment_summary.query.xml | 2 +- .../queries/study/Treatment Orders.query.xml | 181 ++++++++++++++++++ ...-17.21.sql => onprc_ehr-17.705-17.706.sql} | 0 .../sources/BehaviorExamStoreCollection.js | 4 +- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 10 +- .../onprc_ehr/dataentry/NecropsyFormType.java | 10 +- 20 files changed, 549 insertions(+), 129 deletions(-) create mode 100644 onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview_org.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leasefee_rateChargeItem.sql create mode 100644 onprc_ehr/resources/queries/study/Treatment Orders.query.xml rename onprc_ehr/resources/schemas/dbscripts/sqlserver/{onprc_ehr-17.20-17.21.sql => onprc_ehr-17.705-17.706.sql} (100%) diff --git a/extscheduler/resources/views/weeklyTest.html b/extscheduler/resources/views/weeklyTest.html index 332e0a906..7d98e834d 100644 --- a/extscheduler/resources/views/weeklyTest.html +++ b/extscheduler/resources/views/weeklyTest.html @@ -80,7 +80,7 @@ LABKEY.Query.selectRows({ schemaName: 'extscheduler', queryName: 'Events', - columns: 'Id,ResourceId,Name,StartDate,EndDate,UserId,Alias,Owner', + columns: 'Id,ResourceId,Name,StartDate,EndDate,UserId,Alias,Owner,Comments,Quantity', success: function(data){ // need to convert the date fields from a string to JS Date object diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql new file mode 100644 index 000000000..6e83cf69b --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql @@ -0,0 +1,91 @@ +SELECT r.Id, +r.date as BillingDate, +r.enddate as ReleaseDate, +r.CenterProject, +r.AliasAtTime, + +--r.ageinyears, +--r.AgeGroup, +r.projectedReleaseCondition, +r.assignCondition, +r.releaseCondition, +r.releaseType, +r.AgeAtAssignment as AgeAtTime, +r.item as ChargeName, +r.ServiceCenter, +Case + When r.item = 'Lease Fee Adjustment' then a.leaseCharge1.name + else null + end as OriginalLeaseType, +a.leaseCharge2 as FinalLeaseType, +r.AssignmentType as ChargeCategory, +r.CalculatedRate as UnitCost, +cr.unitCost as NIHRate, +--r.DayLease, + +--case statement when dayeleaselength > 0 then dayleasr leanth else 1 as quantity +case + when r.DayLeaseLength> 0 then r.dayleaseLength + Else 1 + End as Quantity, +--Credit Alias Need to +r.MultipleAssignments, +--r.date, +r.projectedRelease, +r.datefinalized, +--r.releaseCondition, +--r.releaseType, +r.remark, +r.alias, +r.ChargeID, +--r.Item, +r.exemptionRate, +r.Multiplier, +r.subsidy, + +--r.revisedChargeID, +r.revisedSubsidy, +r.leasetype, +r.ResearchOwned, +r.farate, +r.removesubsidy, +r.canRaiseFA, +r.BirthAssignment, +r.BirthType, +case + When d.creditResource is not Null then d.creditResource + Else 'p51' + End as CreditTo, +Case +When d.creditResource is not Null then d.creditTo + else ca.account + End as CreditAccount, +case + when r.DayLeaseLength> 0 then (r.dayleaseLength * r.CalculatedRate) + when r.revisedrate is not null and r.revisedrate > r.CalculatedRate then (r.revisedRate - r.CalculatedRate) + when r.revisedrate is not null and r.revisedrate < r.CalculatedRate then (r.CalculatedRate - r.RevisedRate) + + Else (1 * r.CalculatedRate) + End as TotalCost, +r.revisedRate + + +--Fields to Add +--Is Exemption +--Is Non Standard Rate +--Ie Manually Entered +--Is Adjustment/Reversal +---Missing Alias +--Alias Accepting Charges +--Expired Alias +-->45 Days Olde +--Is Assigned at Tom +--IS Assigned to Protocol at Time + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeRates_2020 r + left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeReleaseAdjustment a on a.id = r.id and a.date = r.date + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates cr on r.chargeID = cr.chargeID and (cr.startDate <= r.date and cr.enddate >= r.date or cr.enddate is null) + left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.creditAccount ca on ca.chargeID = r.chargeID and (r.Date > ca.startDate and r.Date <= ca.enddate) + --left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates cr on r.chargeID = cr.chargeID and (cr.startDate <= r.date and cr.enddate >= r.date or cr.enddate is null) + --left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.LeaseFeeRates_CreditTo ct on r.chargeID = ct.chargeID and ct.id <= r.id and ct.assignmentDate = r.date + Left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.date = d.date and r.project = d.project \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql index 642b3b85f..77f72a263 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql @@ -39,7 +39,9 @@ Case End as BirthType, Case + --When da.id when ( a.date = a.id.birth.date and t.id is not null) then 'TMB Birth' + when a.project.use_category = 'Research' then 'Research' Else a.project.use_category end @@ -64,12 +66,20 @@ Case Case when (Select Count(a2.project.name) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) > 2 then 'Over 2 Assignments' + when tmb.id is not null then 'TMB Dam' when (Select Count(a2.project.name) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) = 2 then 'Dual Assigned' End as MultipleAssignments, --(Select a2.project.name from study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) as DualAssignment, - +Case + When da.project is not null and da.dualassignment = a.project then da.project.name + else null + End as CreditResource, +Case + When da.project is not null and da.dualassignment = a.project then da.project.account + else null + End as CreditTo, a.date, @@ -100,5 +110,9 @@ FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assig left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.tmbBirth t on a.id = t.id left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.birth_resourceDam d on a.id = d.id --left outer join study.tmbdam t on t.id = a.id.birth.dam +Left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.dualassigned da on da.id = a.id and (da.dualassignment = a.project + and (da.enddate is null or da.enddate > a.date) and (da.dualenddate is null or da.Dualenddate > a.date)) +Left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.tmbDam tmb on tmb.id = a.id and (tmb.date <= a.date and tmb.enddate >= a.date or tmb.endDate is Null) where a.datefinalized >= startDate and (a.datefinalized <= enddate or a.enddate is null) + and a.id not like '[a-z]%' \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql index 856b560f6..11bbff8ae 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql @@ -15,84 +15,72 @@ COndition Code Change Not if ESPF one use Animal Obese - TMB - ESPF --Update 2020-01-10 Changes ESPF to U42 Expanded SPF Lease so that will properly display +--2020-01-15 Update to handle TMB Adult Assignment + */ SELECT l.id, - Case --Research Owned Animal - When l.researchowned = 'yes' then 'researchOwned' +When l.researchowned = 'yes' then 'researchOwned' --Adult Research Assignment P51 Animal (animal unassigned and adult) ----**Dual Assigned Obese JMac Control Infant Lease - When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and (l.id !=r.id or r.id is null) then 'Obese JMac Control Infant' +When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and (l.id !=r.id or r.id is null) then 'Obese JMac Control Infant' ----**Dual Assigned Obese JMac WSD Infant Lease - When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' +When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' - --Adult Day Lease Condition Change for Research Assigned Adults - remove Age restriction - When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition = l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null ) then 'Day Lease Research Assignment P51 NHP NC' - --Adult Day L:ease No Condition Change - When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition != l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null) then 'Day Lease Research Assignment P51 NHP Condition Change' +--Adult Day Lease Condition Change for Research Assigned Adults - remove Age restriction +When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition = l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null ) then 'Day Lease Research Assignment P51 NHP NC' +--Adult Day L:ease No Condition Change +When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition != l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null) then 'Day Lease Research Assignment P51 NHP Condition Change' --Dual assigned ESPF using different Chared Code - When da.project.Name = '0492-03' then 'U42 Expanded SPF Lease' +When da.project.Name = '0492-03' then 'U42 Expanded SPF Lease' --Dual assigned TMB Male on Day Lease - When l.agegroup = 'Adult' and da.project.name = '0300' and l.dayLease = 'yes' then 'TMB Adult Day Lease' +When l.agegroup = 'Adult' and da.project.name = '0300' and l.dayLease = 'yes' then 'TMB Adult Day Lease' ---Dual assigned Obese Male Day Lease - When l.agegroup = 'Adult' and da.project.name = '0833' and l.dayLease = 'yes' then 'OBESE Adult Day Lease' +/*********Dual Assigned TMB Dam */ +When l.MultipleAssignments = 'TMB Dam' then 'Animal Lease Fee -TMB' --Full LEase P51 adult - When l.id.age.ageinyears > 1 and l.daylease <> 'yes' and (da.project.name <> '0833' or da.project.Name is Null) then 'Research Assignment P51 Adult' +When l.id.age.ageinyears > 1 and l.daylease <> 'yes' and (da.project.name <> '0833' or da.project.Name is Null) then 'Research Assignment P51 Adult' --**Dual Assigned TMB-Dam Assigned Use lease_TMB as Process -------------------------------------------------------------------------------------------------------- + -- For No charge Dam is Dual assigned to TMB and to the Project and Infant is assigned to the Project - THe lease for infant is built into the TMB Lease of the Dam - WHEN L.Birthtype = 'TMBResearchAssignment' then 'TMB No Charge' +WHEN L.Birthtype = 'TMBResearchAssignment' then 'TMB No Charge' --**Dual Assigned TMB Dam Not Assigned ---------------------------------------------------------------------------------------------------------------------------- -- For this the INfant and Dam are not assigned to the same project and the dam is assigned to TMB - WHEN L.Birthtype = 'TMB DAm Not Assigned' then 'TMB Full P 51 Rate Lease' +WHEN L.Birthtype = 'TMB DAm Not Assigned' then 'TMB Full P 51 Rate Lease' -- TMB Dam is TMB and is assigned to Research to produce infant - -- When l.id in (Select d1.id from study.tmbdam d1 where d1.id = l.id and d1.date < l.date and l.enddate is Null) and l.project.Use_category = 'Research' --- then 'TMB Dam Research Assignment' - - +-- When l.id in (Select d1.id from study.tmbdam d1 where d1.id = l.id and d1.date < l.date and l.enddate is Null) and l.project.Use_category = 'Research' +-- then 'TMB Dam Research Assignment' --Infant born to Resource Dam - When l.birthType = 'Born to Resource Dam' then l.birthType - - ---Adult Day Lease Condition Change ------------------------------------------------------------------------------------------------------------ --- This is better handled separately --- when (Select l2.DayLeaseConditionChange from study.lease_DayLeaseAdult l2 where l2.id = l.id) = 'Yes' and l.dayLease = 'yes' Then 'Adult Day Lease With Condition Change' - - ---handle Birth to resource and research at birth --handle it - --- when (Select l2.DayLeaseConditionChange from study.lease_DayLeaseAdult l2 where l2.id = l.id) = 'No' and l.dayLease = 'yes' Then 'Adult Day Lease No Condition Change' +When l.birthType = 'Born to Resource Dam' then l.birthType -/*********Dual Assigned ESPFTMB Birth */ - When da.project.Name = '0492-03' then 'U42 Expanded SPF Lease' ----Dual Assigned Obese JMac Infant or Dam Day Lease = No condition Code CHanges - if change full lease --need to change to also incldue if the damn is there - When da.project.name = '0622-01' and l.daylease = 'yes' then 'Obese 0622-01 Day Lease' +When da.project.name = '0622-01' and l.daylease = 'yes' then 'Obese 0622-01 Day Lease' ----**Dual Assigned Obese JMac Control Infant Lease - When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id !=r.id then 'Obese JMac Control Infant' +When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id !=r.id then 'Obese JMac Control Infant' ----**Dual Assigned Obese JMac WSD Infant Lease - When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' +When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' ----**Dual Assigned Obese Adult Day Lease - When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'yes' then 'OBESE Adult Day Lease' +When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'yes' then 'OBESE Adult Day Lease' ----**Dual Assigned Obese Adult Male Lease - When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) != 'Terminal' then 'OBESE Adult Male Lease' +When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) != 'Terminal' then 'OBESE Adult Male Lease' ----Dual Assigned Obese Adult Male Terminal Lease - When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) = 'Terminal' then 'OBESE Adult Terminal Leasel' +When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) = 'Terminal' then 'OBESE Adult Terminal Leasel' --when Adult Animal Assigned to Research project - when l.agegroup = 'adult' and da.project ='0300' then 'Aninal Lease Fee -TMB' +--when l.agegroup = 'adult' and da.project ='0300' then 'Aninal Lease Fee -TMB' --Infant Research Assignment P51 Animal Day Lease ------------------------------------------------------------------------------------------------------- - When l.id.age.ageinyears < 1 and l.daylease = 'yes' then 'Day Lease Research Assignment P51 Infant' +When l.id.age.ageinyears < 1 and l.daylease = 'yes' then 'Day Lease Research Assignment P51 Infant' --Infant Research Assignment P51 Animal------------------------------------------------------------------------------------------------------- - When l.ageatAssignment < 1 then 'Research Assignment P51 Infant' +When l.ageatAssignment < 1 then 'Research Assignment P51 Infant' diff --git a/onprc_billing/resources/queries/onprc_billing/invoiceditems.query.xml b/onprc_billing/resources/queries/onprc_billing/invoiceditems.query.xml index 466d7d0ca..600842dde 100644 --- a/onprc_billing/resources/queries/onprc_billing/invoiceditems.query.xml +++ b/onprc_billing/resources/queries/onprc_billing/invoiceditems.query.xml @@ -3,7 +3,7 @@ Invoiced Items - org.labkey.ehr.table.DefaultEHRCustomizer + Row Id diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql index a2f3646d4..c8b7ccc23 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql @@ -1,10 +1,12 @@ --Corrested Issue with Adjustments and loading into Test +--20200111 - changed source from rate data to a passthru with a lookup of rate name and unit cost SELECT d.Id, r.leasetype, d.ResearchOwned, d.project, --integer - d.ProjectAlias, + d.project.name as CenterProject, + r.AliasAtTime, d.AgeAtAssignment, d.ageinyears, d.AgeGroup, @@ -14,6 +16,8 @@ SELECT d.Id, d.DayLease, d.DayLeaseLength, --integer d.MultipleAssignments, + d.CreditResource as dualassignment, + null as creditto, d.date, d.projectedRelease, d.enddate, @@ -30,11 +34,16 @@ SELECT d.Id, r.ChargeID, --integer i.Name as Item, i.DepartmentCode as ServiceCenter, - RateCalc(d.alias,r.chargeID,d.project,d.Date,d.farate) as CalculatedRate, - r.revisedChargeID + r.exemptionRate, + r.Multiplier, + r.subsidy, + RateCalc(r.AliasAtTime,r.chargeID,d.project,d.Date,d.farate) as CalculatedRate, + null as revisedRate, + r.revisedChargeID, + r.revisedSubsidy -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateData r join - Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateChargeItem r join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeableItems i on i.rowID = r.chargeID @@ -45,6 +54,7 @@ select 'automatic_adjustment' as AssignmentType, '' as researchOwned, a.projectID, --intege + a.project.name as CenterProject, a.alias, a.ageattime, 1 as ageinYears, --need to run function to return years @@ -55,6 +65,8 @@ select '' as DayLease, '' as DayLeaseLength, --integer '' as MultipleAssignments, + null as dualassignment, + null as creditto, a.date, a.enddate as projectedrelease, a.enddate, @@ -71,8 +83,13 @@ select a.leaseCharge1, --integer ii.name as Item, ii.DepartmentCode as ServiceCenter, + null as exemptionRate, + null as Multiplier, + null as subsidy, + RateCalc(a.alias,a.leasecharge1,a.projectID, a.date,a.farate) as CalculatedRate, RateCalc(a.alias,a.leasecharge2,a.projectID, a.date,a.farate) as RevisedRate, - a.leaseCharge2 + a.leaseCharge2, + null as RevisedSubsidy FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFeeReleaseAdjustment a join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeableItems ii on ii.rowID = a.chargeID @@ -81,21 +98,28 @@ join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.on Union + Select r.id, 'Misc Charge', null as researchOwned, r.project, + r.project.name as CenterProject, r.account.alias, null as ageatTime, null as ageInYears, null as AgeGroup, null as BirthAssignment, null as BirthType, - 'Misc Charge' as AssignmentTypeNA, + case + When r.chargeCategory is not Null then r.chargeCategory + Else 'Misc Charge' + End as AssignmentTypeNA, null as DayLease, null as DayLeaseLength, --integer null as MultipleAssignments, + null as dualassignment, + null as creditto, r.date, null as projectedrelease, null as enddate, @@ -111,9 +135,15 @@ Select null as canRaiseFA, r.chargeID, --integer r.chargeID.Name as Item, - r.serviceCenter as ServiceCenter, + r.serviceCenter as ServiceCenter, + null as exemptionRate, + Null as Multiplier, + null as Subsidy, + r.rateCalc, - null as rate2 + null as RevisedRate, + null as rate2, + null as RevisedSubsidy diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview.sql b/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview.sql index d0ed1c278..da8b30591 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview.sql @@ -1,60 +1,55 @@ -SELECT t.id, -t.CenterProject, -t.alias, -a.aliasType, -a.aliastype.removesubsidy, -a.aliastype.CanRaiseFa, - -t.leasetype, -t.assignmentdate, - - -t.chargeId, -r.chargeID.CanRaiseFA as Chargeid_CanRaiseFA, -t.RevisedChargeID, ---Cost for Original Lease, baswed on Projected release Type - - - - --for adjustments, this is the first lease charge - - - --for adjustments, this is the second lease charge ---Review of Data relating to Alias and Charge Rate ---Is EWxempt - ---Is Non Standard Rate - - ---lacks Rate - - ---Is accepting Charges +SELECT r.id, +r.CenterProject, +r.ProjectID, +r.CurrentAlias, +r.AliasAtTime, +r.RemoveSubsidy, +r.leasetype, +r.assignmentdate, +r.code, +r.ProjectedReleaseCode, +r.AssignmentAge, +r.chargeId, +r.subsidy, +r.ChargeItem, +r.unitCost, +r.multiplier, +r.ExemptionRate, +r.RevisedChargeID, +r.RevisedItem, +r.RevisedSubsidy, +r.RevisedUnitCost, +Case + when r.ExemptionRate is not null then ('Exemption Rate: ' || CAST(r.ExemptionRate AS varchar(100))) + When r.multiplier is not null THEN ('Multiplier: ' || CAST(r.multiplier AS varchar(100))) + Else Null +End as isExemption, +--Is Non Standard Rate Looks to see if +--Ie Manually Entered +--Is Adjustment/Reversal + +---Missing Alias +Case When r.aliasAtTime is Null then 'y' + else 'n' + End As Missingalias, +--Alias Accepting Charges CASE WHEN a.aliasEnabled IS NULL THEN 'N' WHEN a.aliasEnabled != 'Y' THEN 'N' ELSE null END as isAcceptingCharges, - ---Is Expired Account -CASE - WHEN (a.budgetStartDate IS NOT NULL AND CAST(a.budgetStartDate as date) > CAST(t.assignmentdate as date)) THEN 'Prior To Budget Start' - WHEN (a.budgetEndDate IS NOT NULL AND CAST(a.budgetEndDate as date) < CAST(t.assignmentdate as date)) THEN 'After Budget End' +--Expired Alias + CASE + WHEN (a.budgetStartDate IS NOT NULL AND CAST(a.budgetStartDate as date) > CAST(r.assignmentdate as date)) THEN 'Prior To Budget Start' + WHEN (a.budgetEndDate IS NOT NULL AND Cast(a.budgetEndDate as date ) < CAST(r.assignmentdate as date)) THEN 'After Budget End' WHEN (a.projectStatus IS NOT NULL AND a.projectStatus != 'ACTIVE' AND a.projectStatus != 'No Cost Ext' AND a.projectStatus != 'Partial Setup') THEN 'Grant Project Not Active' ELSE null END as isExpiredAccount, -CASE WHEN a.alias IS NULL THEN 'Y' ELSE null END as isMissingAccount, -CASE WHEN a.fiscalAuthority.faid IS NULL THEN 'Y' ELSE null END as isMissingFaid, - +-->45 Days Olde +CASE WHEN (TIMESTAMPDIFF('SQL_TSI_DAY', r.assignmentDate, curdate()) > 45) THEN 'Y' ELSE null END as isOldCharge, +--Is Assigned at Time +--IS Assigned to Protocol at Time -FROM leaseFee_Test t, -"/ONPRC/ADMIN/FINANCE".onprc_billing.chargeRates r, -"/ONPRC/ADMIN/FINANCE".onprc_billing.aliases a, -"/ONPRC/ADMIN/FINANCE".onprc_billing_public.chargeRateExemptions e -where r.chargeId = t.chargeId and t.alias = a.alias -and(r.startDate <= t.assignmentdate and r.endDateCoalesced > t.assignmentdate) -and (CAST(t.assignmentDate AS DATE) >= CAST(e.startDate AS DATE) -and (CAST(t.assignmentDate AS DATE) <= e.enddateCoalesced OR e.enddate IS NULL) -AND t.chargeId = e.chargeId -AND Cast(t.Centerproject as varchar(20)) = Cast(e.project as varchar(20))) \ No newline at end of file +FROM leasefee_rateChargeItem r + Left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.aliases a on r.aliasatTime = a.alias \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview_org.sql b/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview_org.sql new file mode 100644 index 000000000..42fbd4aed --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/leaseFee_RateReview_org.sql @@ -0,0 +1,65 @@ +SELECT t.id, +t.CenterProject, +t.alias, +a.aliasType, +a.aliastype.removesubsidy, +a.aliastype.CanRaiseFa, + +t.leasetype, +t.assignmentdate, + + +t.chargeId, +r.chargeID.CanRaiseFA as Chargeid_CanRaiseFA, +t.RevisedChargeID, +--Is Exemption review exemption and mulitpler +--Is Non Standard Rate +--Is Exemption +--Is Non Standard Rate +case + When e.rowID is not null then 'Y' + WHEN (rc.multiplier IS NOT NULL) THEN ('Multiplier: ' || CAST(rc.multiplier AS varchar(100))) + ELSE null + ENd as isExemption, +--Ie Manually Entered +--Is Adjustment/Reversal +---Missing Alias +--Alias Accepting Charges +--Expired Alias +-->45 Days Olde +--Is Assigned at Tom +--IS Assigned to Protocol at Time +--Ie Manually Entered +--Is Adjustment/Reversal +---Missing Alias + + +-->45 Days Olde +--Is Assigned at Tom +--IS Assigned to Protocol at Time +--Is accepting Charges +CASE + WHEN a.aliasEnabled IS NULL THEN 'N' + WHEN a.aliasEnabled != 'Y' THEN 'N' + ELSE null + END as isAcceptingCharges, + +--Is Expired Account +CASE + WHEN (a.budgetStartDate IS NOT NULL AND CAST(a.budgetStartDate as date) > CAST(t.assignmentdate as date)) THEN 'Prior To Budget Start' + WHEN (a.budgetEndDate IS NOT NULL AND CAST(a.budgetEndDate as date) < CAST(t.assignmentdate as date)) THEN 'After Budget End' + WHEN (a.projectStatus IS NOT NULL AND a.projectStatus != 'ACTIVE' AND a.projectStatus != 'No Cost Ext' AND a.projectStatus != 'Partial Setup') THEN 'Grant Project Not Active' + ELSE null + END as isExpiredAccount, +CASE WHEN a.alias IS NULL THEN 'Y' ELSE null END as isMissingAccount, +CASE WHEN a.fiscalAuthority.faid IS NULL THEN 'Y' ELSE null END as isMissingFaid, + + + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFee_RateData t + left join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRates r on r.chargeID = t.chargeID and t.alias = r.AliasAtTIme + Left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.aliases a on t.alias = a.alias + Left Join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.chargeRateExemptions e e. + Left Join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateChargeItem rc + diff --git a/onprc_billing/resources/queries/onprc_billing/leasefee_rateChargeItem.sql b/onprc_billing/resources/queries/onprc_billing/leasefee_rateChargeItem.sql new file mode 100644 index 000000000..19b297855 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/leasefee_rateChargeItem.sql @@ -0,0 +1,34 @@ +--20200113 Updated to look up active alias at time of assignment - Critical when dealing with Historic assignments +SELECT d.id, +d.CenterProject, +d.ProjectID, +d.alias as CurrentAlias, +h.account as AliasAtTime, +h.account.aliastype.removeSubsidy as RemoveSubsidy, +d.leasetype, +d.assignmentdate, +d.code, +d.ProjectedReleaseCode, +d.AssignmentAge, +d.chargeId, +r.chargeId.activeRate.subsidy, +r.chargeID.name as ChargeItem, +r.unitCost , +p.multiplier, +e.UnitCost as ExemptionRate, +d.RevisedChargeID, +r1.chargeID.Name AS RevisedItem, +r1.chargeID.activeRate.subsidy as RevisedSubsidy, +r1.unitCost as RevisedUnitCost, +d.quantity +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leasefee_rateData d + --Join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.Leasefee_leaseType t on d.id = t.id + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates r on d.chargeID = r.chargeID + and (d.assignmentdate >= r.startDate and d.assignmentdate <= r.enddate) + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates r1 on d.RevisedchargeID = r1.chargeID and (d.assignmentdate >= r1.startDate and d.assignmentdate <= r1.enddate) + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.projectAccountHistory h on h.project = d.projectID and (d.assignmentdate >= h.startDate and d.assignmentDate <= h.enddate) +--add query for exemption item + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRateExemptions e on e.chargeID = d.chargeID and e.project = d.projectID + and (d.assignmentdate >= e.startDate and d.assignmentDate <= e.enddate) +--add project multipler + left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.ProjectMultipliers p on p.account = h.account and (d.assignmentDate >= p.startDate and d.assignmentdate <= p.enddate) \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql b/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql index 5b42b3f1c..5595bab35 100644 --- a/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql +++ b/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql @@ -58,6 +58,28 @@ FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.on AND lf.active = true) where l.daylease <> 'yes' +UNION + +SELECT l.id, +l.project.name as CenterProject, +l.project.project as ProjectID, +l.alias, +l.leasetype, +l.assignmentdate, +l.assignCondition.code, + +l.projectedReleaseCondition.code as ProjectedReleaseCode, +Cast(l.ageAtAssignment as Integer) as AssignmentAge, +lf.chargeId, +Null as RevisedChargeID, + +1 as quantity + +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l + JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( + lf.chargeId.Name = 'Animal Lease Fee - TMB' and lf.active = true) + +where (l.leasetype = 'Animal Lease Fee -TMB') and l.daylease <> 'yes' UNION diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml b/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml index 387047268..201c282a0 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesNotBilled_Virology.query.xml @@ -3,7 +3,7 @@
    Manually Entered Charges - org.labkey.ehr.table.DefaultEHRCustomizer + diff --git a/onprc_billing/resources/queries/onprc_billing/perDiemFeeDefinition.query.xml b/onprc_billing/resources/queries/onprc_billing/perDiemFeeDefinition.query.xml index 11eb6e585..d7d9cc932 100644 --- a/onprc_billing/resources/queries/onprc_billing/perDiemFeeDefinition.query.xml +++ b/onprc_billing/resources/queries/onprc_billing/perDiemFeeDefinition.query.xml @@ -3,7 +3,7 @@
    Per Diem Fee Definition - org.labkey.ehr.table.DefaultEHRCustomizer + diff --git a/onprc_billing/resources/schemas/onprc_billing.xml b/onprc_billing/resources/schemas/onprc_billing.xml index 0e9b9dddb..7bc72c47a 100644 --- a/onprc_billing/resources/schemas/onprc_billing.xml +++ b/onprc_billing/resources/schemas/onprc_billing.xml @@ -1508,7 +1508,7 @@
    - org.labkey.ehr.table.DefaultEHRCustomizer + DETAILED Annual Rate Change diff --git a/onprc_ehr/resources/queries/ehr/requests.query.xml b/onprc_ehr/resources/queries/ehr/requests.query.xml index efe747489..d170de320 100644 --- a/onprc_ehr/resources/queries/ehr/requests.query.xml +++ b/onprc_ehr/resources/queries/ehr/requests.query.xml @@ -2,7 +2,7 @@
    - org.labkey.ehr.table.DefaultEHRCustomizer + /ehr/requestDetails.view?formtype=${formtype}&requestid=${requestid} @@ -112,13 +112,8 @@ - - - - - - - Views + + Grid views Export @@ -126,15 +121,6 @@ Print - - - - - Page Size - - - -
    diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml index 8210a6a70..ab4f169d4 100644 --- a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml +++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_summary.query.xml @@ -3,7 +3,7 @@ Vet Assignment - org.labkey.ehr.table.DefaultEHRCustomizer + diff --git a/onprc_ehr/resources/queries/study/Treatment Orders.query.xml b/onprc_ehr/resources/queries/study/Treatment Orders.query.xml new file mode 100644 index 000000000..67ffea702 --- /dev/null +++ b/onprc_ehr/resources/queries/study/Treatment Orders.query.xml @@ -0,0 +1,181 @@ + + + +
    + /EHR/treatmentDetails.view?key=${lsid} + + + + + + + + + + Begin Date + yyyy-MM-dd HH:mm + + + End Date + false + yyyy-MM-dd HH:mm + + + + Charge To + + ehr + project + project + + + + Category + + ehr_lookups + drug_categories + value + + + Depending on what is selected, the treatment will appear on a different schedule (ie. Clinical, Surgical, etc) + + + Reason + + + + Credit To + + ehr_lookups + medicationChargeType + value + + + No Charge + + + Short Name + + + false + Treatment + + ehr_lookups + snomed + code + + + + Is Billable + + ehr_lookups + yesno + value + + + No + + + Qualifier + + + Frequency + + ehr_lookups + Treatment_Frequencies_Active + rowid + + + + Route + + ehr_lookups + routes + route + + + 40 + + + Drug Conc + + + Conc Units + + ehr_lookups + conc_units + unit + + + + + Dosage + + + Dosage Units + + ehr_lookups + dosage_units + unit + + + + + Volume + + + Volume Units + + ehr_lookups + volume_units + unit + + + + + Amount + + + Amount Units + + ehr_lookups + amount_units + unit + + + + + false + Ordered By + + + false + Modified By + + + false + Modified Date + + + false + Last Administered + /query/executeQuery.view?schemaName=study& + query.queryName=Drug%20Administration& + query.parentid~eq=${objectid}& + + + + + + + + + + + Ordered By + + +
    +
    + + \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.20-17.21.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.705-17.706.sql similarity index 100% rename from onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.20-17.21.sql rename to onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.705-17.706.sql diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js index 1e771dfac..d0d4143e2 100644 --- a/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/BehaviorExamStoreCollection.js @@ -11,8 +11,10 @@ Ext4.define('ONPRC_EHR.data.sources.BehaviorExamStoreCollection', { this.mon(EHR.DemographicsCache, 'casecreated', this.onCaseCreated, this); }, + //Modified: 1-15-2020 R. Blasa onCaseCreated: function(id, category, caseId){ - if (category != 'Clinical') + + if (category != 'Behavior') return; //NOTE: if we opened a case from this form, tag the SOAP note diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 96d3cb632..1b27b919b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -53,6 +53,7 @@ import org.labkey.onprc_ehr.buttons.AssignmentReleaseConditionButton; import org.labkey.onprc_ehr.buttons.BulkEditRequestsButton; import org.labkey.onprc_ehr.buttons.ChangeProjectedReleaseDateButton; +import org.labkey.onprc_ehr.buttons.CreateNecropsyRequestButton; import org.labkey.onprc_ehr.buttons.CreateProjectButton; import org.labkey.onprc_ehr.buttons.HousingTransferButton; import org.labkey.onprc_ehr.buttons.ManageFlagsButton; @@ -113,7 +114,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 17.705; + return 17.706; } @Override @@ -383,6 +384,7 @@ public String toString() EHRService.get().registerActionOverride("cageDetails", this, "views/cageDetails.html"); EHRService.get().registerActionOverride("animalSearch", this, "views/animalSearch.html"); EHRService.get().registerActionOverride("animalHistory", this, "views/animalHistory.html"); + EHRService.get().registerActionOverride("serviceRequests", this, "views/serviceRequests.html"); //Added: 10-2-2017 R.Blasa displays onperc version of enterData.view EHRService.get().registerActionOverride("enterData", this, "views/enterData.html"); @@ -405,6 +407,7 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SingleSurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyFormType.class, this)); + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyRequestForm.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(BiopsyFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PathologyTissuesFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ClinicalReportFormType.class, this)); @@ -576,6 +579,11 @@ public String toString() EHRService.get().registerHistoryDataSource(new org.labkey.api.ehr.history.DefaultAnimalRecordFlagDataSource(this)); EHRService.get().registerHistoryDataSource(new ONPRCClinicalRemarksDataSource(this)); + EHRService.get().registerMoreActionsButton(new CreateNecropsyRequestButton(this), "study", "encounters"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "encounters"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "tissue_samples"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "organ_weights"); + EHRService.get().registerOptionalClinicalHistoryResources(this); EHRService.get().registerLabworkType(new ONPRCUrinalysisLabworkType(this)); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java index 4d0344f3e..99013427c 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyFormType.java @@ -62,9 +62,13 @@ public NecropsyFormType(DataEntryFormContext ctx, Module owner) //new PathologyTissueDistFormSection(), //new PathologyFormSection("study", "measurements", "Measurements"), new PathologyDiagnosesFormSection("study", "histology", "Histologic Findings"), - new PathologyDiagnosesFormSection("study", "pathologyDiagnoses", "Diagnoses"), - new SimpleFormSection("study", "tissue_samples", "Tissue Samples", "onprc_ehr-dragdropgridpanel"), - new SimpleFormSection("study", "organ_weights", "Organ Weights", "onprc_ehr-dragdropgridpanel") + new PathologyDiagnosesFormSection("study", "pathologyDiagnoses", "Diagnoses") + + //Removed: 2-4-2020 R.Blassa Commented temporarily Note: This form was excluded 17.2 version +// new SimpleFormSection("study", "tissue_samples", "Tissue Samples", "onprc_ehr-dragdropgridpanel") + + //Removed: 1-29-2020 R.Blassa Commented temporarily Note: This form was excluded 17.2 version + // new SimpleFormSection("study", "organ_weights", "Organ Weights", "onprc_ehr-dragdropgridpanel") )); for (FormSection s : this.getFormSections()) From 5ad9dabc1542b61ad114edcc18ac838e529ec855 Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 20:16:58 -0700 Subject: [PATCH 11/49] Merge from onprc19.1 r.65053 to 65061 --- onprc_billing/resources/etls/ogaSynch2019.xml | 2 +- .../sqlserver/onprc_billing-20.101-20.102.sql | 13 ++++ .../sqlserver/onprc_billing-20.102-20.103.sql | 52 ++++++++++++++ onprc_ehr/resources/etls/eIACUCToPrimce.xml | 10 +-- .../sqlserver/onprc_ehr-20.101-20.102.sql | 50 ++++++++++++++ .../sqlserver/onprc_ehr-20.102-20.103.sql | 26 +++++++ .../sqlserver/onprc_ehr-20.103-20.104.sql | 32 +++++++++ .../sqlserver/onprc_ehr-20.104-20.105.sql | 41 ++++++++++++ .../sqlserver/onprc_ehr-20.105-20.106.sql | 28 ++++++++ .../sqlserver/onprc_ehr-20.106-20.107.sql | 67 +++++++++++++++++++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 60 ++++++----------- 11 files changed, 335 insertions(+), 46 deletions(-) create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.101-20.102.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.102-20.103.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.101-20.102.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.102-20.103.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.103-20.104.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.104-20.105.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.105-20.106.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.106-20.107.sql diff --git a/onprc_billing/resources/etls/ogaSynch2019.xml b/onprc_billing/resources/etls/ogaSynch2019.xml index cab3cf430..daa35a212 100644 --- a/onprc_billing/resources/etls/ogaSynch2019.xml +++ b/onprc_billing/resources/etls/ogaSynch2019.xml @@ -16,7 +16,7 @@ Import to OGA Sync in Prime - + diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.101-20.102.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.101-20.102.sql new file mode 100644 index 000000000..8bcb5091d --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.101-20.102.sql @@ -0,0 +1,13 @@ +-- Adds change inflation rate to 3 position decimal +-- add primary key and identity key +--If the field exists in the current build we drop the column and recreate +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [COMMENTS]; +ALTER TABLE onprc_billing.aliases ADD [COMMENTS] VarChar(255) Null; + +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [dateDisabled]; +ALTER TABLE onprc_billing.aliases ADD [dateDisabled] DATETIME Null; + +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [PPQNumber]; +ALTER TABLE onprc_billing.aliases ADD [PPQNumber] VARCHAR(25) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [PPQDate]; +ALTER TABLE onprc_billing.aliases ADD [PPQDate] DATETIME Null; diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.102-20.103.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.102-20.103.sql new file mode 100644 index 000000000..25154f119 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.102-20.103.sql @@ -0,0 +1,52 @@ +DROP TABLE IF EXISTS onprc_billing.ogaSynch +GO + +CREATE TABLE [onprc_billing].[ogasynch]( + [lastIndexed] [datetime] NULL, + [modifiedBy] [int] NULL, + [container] [dbo].[ENTITYID] NOT NULL, + [modified] [datetime] NULL, + [created] [datetime] NULL, + [entityId] [dbo].[ENTITYID] NOT NULL, + [createdBy] [int] NULL, + [ADFM EMP NUM] [int] NULL, + [ADFM FULL NAME] [nvarchar](4000) NULL, + [ADFM LAST NAME] [nvarchar](4000) NULL, + [ADFM FIRST NAME] [nvarchar](4000) NULL, + [PI EMP NUM] [int] NULL, + [PI FULL NAME] [nvarchar](4000) NULL, + [PI LAST NAME] [nvarchar](4000) NULL, + [PI FIRST NAME] [nvarchar](4000) NULL, + [PDFM EMP NUM] [int] NULL, + [PDFM FULL NAME] [nvarchar](4000) NULL, + [PDFM LAST NAME] [nvarchar](4000) NULL, + [PDFM FIRST NAME] [nvarchar](4000) NULL, + [AGENCY AWARD NUMBER] [nvarchar](4000) NULL, + [OGA AWARD NUMBER] [nvarchar](4000) NULL, + [OGA AWARD TYPE] [nvarchar](4000) NULL, + [OGA PROJECT NUMBER] [nvarchar](4000) NULL, + [ALIAS] [int] NULL, + [ALIAS ENABLED FLAG] [bit] NULL, + [ALIAS ENABLED FLAG_MVIndicator] [nvarchar](50) NULL, + [PROJECT DESCRIPTION] [nvarchar](4000) NULL, + [APPLICATION TYPE] [int] NULL, + [ACTIVITY TYPE] [nvarchar](4000) NULL, + [AWARD NUMBER] [nvarchar](4000) NULL, + [AWARD SUFFIX] [nvarchar](4000) NULL, + [ORG] [nvarchar](4000) NULL, + [CURRENT BUDGET START DATE] [datetime] NULL, + [CURRENT BUDGET END DATE] [datetime] NULL, + [PROJECT TITLE] [nvarchar](4000) NULL, + [PPQ CODE] [nvarchar](4000) NULL, + [PPQ DATE] [datetime] NULL, + [IACUC NUMBER] [nvarchar](4000) NULL, + [AWARD STATUS] [nvarchar](4000) NULL, + [PROJECT STATUS] [nvarchar](4000) NULL, + [AWARD ID] [int] NULL, + [PROJECT ID] [int] NULL, + [BURDEN SCHEDULE] [nvarchar](4000) NULL, + [BURDEN RATE] [float] NULL, + [faRate] [float] NULL, + [Key] [int] IDENTITY(1,1) NOT NULL +) ON [PRIMARY] +GO \ No newline at end of file diff --git a/onprc_ehr/resources/etls/eIACUCToPrimce.xml b/onprc_ehr/resources/etls/eIACUCToPrimce.xml index 48f787146..1a5f9a847 100644 --- a/onprc_ehr/resources/etls/eIACUCToPrimce.xml +++ b/onprc_ehr/resources/etls/eIACUCToPrimce.xml @@ -16,7 +16,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -36,7 +36,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.101-20.102.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.101-20.102.sql new file mode 100644 index 000000000..efb94f791 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.101-20.102.sql @@ -0,0 +1,50 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.animalGroups Dataset which is populated by the ETL Process + * + */ +CREATE TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_ANIMAL_GROUPS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Parent_Protocol] [varchar](255) NOT NULL, + [Group_ID] [varchar](255) NULL, + [Group_Name] [varchar](255) NULL, + [Species] [varchar](255) NULL, + [SPF_Status] [varchar](255) NULL, + [Weight_Start] [varchar](255) NULL, + [Weight_End] [varchar](255) NULL, + [Age_Start] [varchar](255) NULL, + [Age_End] [varchar](255) NULL, + [Gender] [varchar](255) NULL, + [Number_of_Animals_Max] [int] NULL, + [Breeding_Colony] [int] NULL, + [Non_Standard_Housing_Types] [nvarchar](max) NULL, + [Non_Standard_Housing_Description] [nvarchar](max) NULL, + [Non_Standard_Housing_Frequency_and_Duration][nvarchar](max) NULL, + [Non_Standard_Housing_Monitoring] [nvarchar](max) NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL, + [Restraint] [nvarchar](max) NULL, + [Nutritional_Manipulation_Description] [nvarchar](max) NULL, + [Nutritional_Manipulation_Adverse_Consequences] [nvarchar](max) NULL, + [Nutritional_Manipulation_Health_Assessment] [nvarchar](max) NULL, + [Non_Pharmaceutical_Grade_Drug_Use] [nvarchar](max) NULL, + [Food_Withheld] [int] NULL, + [Water_Withheld] [int] NULL, + [Food_Water_Withheld_Description] [nvarchar](max) NULL, + [Food_Water_Withheld_Justification] [nvarchar](max) NULL, + [Food_Water_Withheld_Adverse_Consequences] [nvarchar](max) NULL, + [Death_As_Endpoint_Number_of_Animals] [nvarchar](max) NULL, + [Death_As_Endpoint_Justification] [nvarchar](max) NULL +) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.102-20.103.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.102-20.103.sql new file mode 100644 index 000000000..719f1c4fe --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.102-20.103.sql @@ -0,0 +1,26 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.IBC_Numberss Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_IBC_NUMBERS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Animal_Group] [varchar](255) NOT NULL, + [IBC_Registration_Number] [varchar](255) NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL +) ON [PRIMARY] +GO \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.103-20.104.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.103-20.104.sql new file mode 100644 index 000000000..eb1c5a1fd --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.103-20.104.sql @@ -0,0 +1,32 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_NON_SURGICAL_PROCS Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_NON_SURGICAL_PROCS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Animal_Group] [varchar](255) NOT NULL, + [NS_Procedure_Name] [varchar](255) NULL, + [Standard_Procedure] [int] NULL, + [Iterations] [int] NULL, + [Deviation] [int] NULL, + [Deviation_Description] [varchar](255) NULL, + [Recovery_Days] [int] NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL +) ON [PRIMARY] +GO + diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.104-20.105.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.104-20.105.sql new file mode 100644 index 000000000..818e499a4 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.104-20.105.sql @@ -0,0 +1,41 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_PROTOCOLS Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_PROTOCOLS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Protocol_ID] [varchar](255) NOT NULL, + [Template_OID] [varchar](32) NULL, + [Protocol_OID] [varchar](255) NULL, + [Protocol_Title] [varchar](255) NULL, + [PI_ID] [varchar](255) NULL, + [PI_First_Name] [varchar](255) NULL, + [PI_Last_Name] [varchar](255) NULL, + [PI_Email] [varchar](255) NULL, + [PI_Phone] [varchar](255) NULL, + [USDA_Level] [varchar](255) NULL, + [Approval_Date] [datetime] NULL, + [Annual_Update_Due] [datetime] NULL, + [Three_year_Expiration] [datetime] NULL, + [Last_Modified] [datetime] NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL, + [PROTOCOL_State] [varchar](250) NULL, + [PPQ_Numbers] [varchar](255) NULL, + [Description] [varchar](255) NULL +) ON [PRIMARY] +GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.105-20.106.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.105-20.106.sql new file mode 100644 index 000000000..851fcbebc --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.105-20.106.sql @@ -0,0 +1,28 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2/17/2018 Jones ga + * This script creates the ONPRC_EHR.PRIME_VIEW_SURGICAL_PROCS Dataset which is populated by the ETL Process + * + */ + +CREATE TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_SURGICAL_PROCS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [OID] [int] NOT NULL, + [Animal_Group] [varchar](255) NOT NULL, + [Standard_Procedure] [int] NULL, + [Iterations] [int] NULL, + [Deviation] [int] NULL, + [Deviation_Description] [varchar](255) NULL, + [Recovery_Days] [int] NULL, + [Surgery_Name] [varchar](255) NULL +) ON [PRIMARY] +GO diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.106-20.107.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.106-20.107.sql new file mode 100644 index 000000000..be24b0485 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.106-20.107.sql @@ -0,0 +1,67 @@ + /* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2020/1/24 Update of Fields to accomodate incoming text straing. + * Manual updated the Database schema to verify that it resolved the issue + * This script creates the ONPRC_EHR.animalGroups Dataset which is populated by the ETL Process + * + */ + + +/****** Object: Table [onprc_ehr].[eIACUC_PRIME_VIEW_ANIMAL_GROUPS] Script Date: 1/24/2020 12:23:44 PM ******/ +DROP TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_ANIMAL_GROUPS] +GO + +/****** Object: Table [onprc_ehr].[eIACUC_PRIME_VIEW_ANIMAL_GROUPS] Script Date: 1/24/2020 12:23:44 PM ******/ +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +CREATE TABLE [onprc_ehr].[eIACUC_PRIME_VIEW_ANIMAL_GROUPS]( + [rowid] [int] IDENTITY(1,1) NOT NULL, + [Parent_Protocol] [varchar](255) NOT NULL, + [Group_ID] [varchar](255) NULL, + [Group_Name] [varchar](255) NULL, + [Species] [varchar](255) NULL, + [SPF_Status] [varchar](255) NULL, + [Weight_Start] [varchar](255) NULL, + [Weight_End] [varchar](255) NULL, + [Age_Start] [varchar](255) NULL, + [Age_End] [varchar](255) NULL, + [Gender] [varchar](255) NULL, + [Number_of_Animals_Max] [int] NULL, + [Breeding_Colony] [int] NULL, + [Non_Standard_Housing_Types] [nvarchar](max) NULL, + [Non_Standard_Housing_Description] [ntext] NULL, + [Non_Standard_Housing_Frequency_and_Duration] [nvarchar](max) NULL, + [Non_Standard_Housing_Monitoring] [nvarchar](max) NULL, + [createdby] [int] NULL, + [created] [datetime] NULL, + [modifiedby] [int] NULL, + [modified] [datetime] NULL, + [Restraint] [nvarchar](max) NULL, + [Nutritional_Manipulation_Description] [nvarchar](max) NULL, + [Nutritional_Manipulation_Adverse_Consequences] [nvarchar](max) NULL, + [Nutritional_Manipulation_Health_Assessment] [nvarchar](max) NULL, + [Non_Pharmaceutical_Grade_Drug_Use] [ntext] NULL, + [Food_Withheld] [int] NULL, + [Water_Withheld] [int] NULL, + [Food_Water_Withheld_Description] [nvarchar](max) NULL, + [Food_Water_Withheld_Justification] [nvarchar](max) NULL, + [Food_Water_Withheld_Adverse_Consequences] [nvarchar](max) NULL, + [Death_As_Endpoint_Number_of_Animals] [nvarchar](max) NULL, + [Death_As_Endpoint_Justification] [nvarchar](max) NULL +) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] +GO + + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 1b27b919b..85244b66f 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 LabKey Corporation + * Copyright (c) 2012-2017 LabKey Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,6 @@ import org.labkey.api.ehr.EHRService; import org.labkey.api.ehr.buttons.ChangeQCStateButton; import org.labkey.api.ehr.buttons.CreateTaskFromIdsButton; -import org.labkey.api.ehr.buttons.CreateTaskFromRecordsButton; -import org.labkey.api.ehr.buttons.DiscardTaskButton; import org.labkey.api.ehr.buttons.EHRShowEditUIButton; import org.labkey.api.ehr.buttons.MarkCompletedButton; import org.labkey.api.ehr.buttons.ReassignRequestButton; @@ -33,33 +31,30 @@ import org.labkey.api.ldk.ExtendedSimpleModule; import org.labkey.api.ldk.buttons.ShowEditUIButton; import org.labkey.api.ldk.notification.NotificationService; -import org.labkey.api.module.AdminLinkManager; import org.labkey.api.module.Module; import org.labkey.api.module.ModuleContext; import org.labkey.api.query.DefaultSchema; import org.labkey.api.query.DetailsURL; import org.labkey.api.query.QuerySchema; import org.labkey.api.resource.Resource; -import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.security.roles.RoleManager; import org.labkey.api.settings.AppProps; import org.labkey.api.util.URLHelper; import org.labkey.api.util.UnexpectedException; -import org.labkey.api.view.ActionURL; -import org.labkey.api.view.NavTree; import org.labkey.api.view.template.ClientDependency; import org.labkey.onprc_ehr.buttons.AnimalGroupCompletedButton; import org.labkey.onprc_ehr.buttons.AssignmentCompletedButton; import org.labkey.onprc_ehr.buttons.AssignmentReleaseConditionButton; import org.labkey.onprc_ehr.buttons.BulkEditRequestsButton; import org.labkey.onprc_ehr.buttons.ChangeProjectedReleaseDateButton; -import org.labkey.onprc_ehr.buttons.CreateNecropsyRequestButton; import org.labkey.onprc_ehr.buttons.CreateProjectButton; +import org.labkey.onprc_ehr.buttons.DiscardTaskButton; import org.labkey.onprc_ehr.buttons.HousingTransferButton; import org.labkey.onprc_ehr.buttons.ManageFlagsButton; import org.labkey.onprc_ehr.buttons.ProtocolEditButton; import org.labkey.onprc_ehr.buttons.VetReviewButton; import org.labkey.onprc_ehr.buttons.VetReviewRecordButton; +import org.labkey.onprc_ehr.buttons.CreateTaskFromRecordButtons; import org.labkey.onprc_ehr.dataentry.*; import org.labkey.onprc_ehr.demographics.ActiveAnimalGroupsDemographicsProvider; import org.labkey.onprc_ehr.demographics.ActiveCasesDemographicsProvider; @@ -68,11 +63,11 @@ import org.labkey.onprc_ehr.demographics.CagematesDemographicsProvider; import org.labkey.onprc_ehr.demographics.FosterChildDemographicsProvider; import org.labkey.onprc_ehr.demographics.HousingDemographicsProvider; -import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.demographics.ParentsDemographicsProvider; import org.labkey.onprc_ehr.demographics.PregnancyConfirmDemographicsProvider; import org.labkey.onprc_ehr.demographics.SourceDemographicsProvider; import org.labkey.onprc_ehr.demographics.TBDemographicsProvider; +import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsEndDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalRecordFlagDataSource; @@ -114,7 +109,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 17.706; + return 20.107; } @Override @@ -298,17 +293,18 @@ private void registerEHRResources() //Added 5-16-2018 R.Blasa EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Date of Last Physical Exam by ID(s)", this, DetailsURL.fromString("/onprc_ehr/PE_ExamHistoryReportbyID.view"), "Routine Clinical Tasks"); - //Added 5-11-2015 New report for Lois Colgin + //Modified: 1-17-2019 R.Blasa try { - EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Laboratory Test Summary", this, new URLHelper("http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fPrimeLaboratory+Report&rs:Command=Render") + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Clinical Pathology Laboratory Summary Report", this, new URLHelper("http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render") { // SSRS is picky about the URI-encoding of the query parameters @Override //Modified: 1-17-2019 R.Blasa public String toString() { - return "http://primateapp.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fAnnual+Reports%2fPrimeLaboratory+Report&rs:Command=Render"; + return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fClinPath%2fPrimeLaboratory+Report&rs:Command=Render"; + } }, "Clinical Pathology"); } @@ -324,6 +320,7 @@ public String toString() { // SSRS is picky about the URI-encoding of the query parameters @Override + //Modified: 1-17-2019 R.Blasa public String toString() { return "http://primateapp3.ohsu.edu/ReportServer/Pages/ReportViewer.aspx?%2fPrime+Reports%2fExposure+Reports%2fDemographicsReportMain&rs:Command=Render"; @@ -384,7 +381,6 @@ public String toString() EHRService.get().registerActionOverride("cageDetails", this, "views/cageDetails.html"); EHRService.get().registerActionOverride("animalSearch", this, "views/animalSearch.html"); EHRService.get().registerActionOverride("animalHistory", this, "views/animalHistory.html"); - EHRService.get().registerActionOverride("serviceRequests", this, "views/serviceRequests.html"); //Added: 10-2-2017 R.Blasa displays onperc version of enterData.view EHRService.get().registerActionOverride("enterData", this, "views/enterData.html"); @@ -407,7 +403,6 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SingleSurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyFormType.class, this)); - EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyRequestForm.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(BiopsyFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PathologyTissuesFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ClinicalReportFormType.class, this)); @@ -426,7 +421,7 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ParentageFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(GeneticAncestryFormType.class, this)); - EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ONPRCBloodDrawFormType.class, this)); + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(BloodDrawFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(AuxProcedureFormType.class, this)); //Modified: 12-13-2016 R.Blasa @@ -526,19 +521,20 @@ public String toString() editBtn.setCopyFilters(false); EHRService.get().registerMoreActionsButton(editBtn, "study", "flags"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Blood Draw For Selected", "Blood Draws", ONPRCBloodDrawFormType.NAME, new String[]{"Blood Draws"}), "study", "demographics"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Blood Draw For Selected", "Blood Draws", BloodDrawFormType.NAME, new String[]{"Blood Draws"}), "study", "demographics"); //EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Weight For Selected", "Weight", "weight", new String[]{"Weight"}), "study", "demographics"); //EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Weight For Selected", "Weight", "weight", new String[]{"Weight"}), "study", "weight"); EHRService.get().registerTbarButton(new HousingTransferButton(this), "onprc_ehr", "housing_transfer_requests"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Blood Draws", ONPRCBloodDrawFormType.NAME), "study", "blood"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Treatments/Medications", TreatmentsFormType.NAME), "study", "drug"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Labwork", LabworkFormType.NAME), "study", "clinpathRuns"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); + //Modified: 1-18-2019 R.Blasa + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Blood Draws", BloodDrawFormType.NAME), "study", "blood"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Treatments/Medications", TreatmentsFormType.NAME), "study", "drug"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Labwork", LabworkFormType.NAME), "study", "clinpathRuns"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); - //Added: 7-29-2017 R.Blasa - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); + //Added: 1-18-2019 R.Blasa + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this), "study", "blood"); @@ -579,32 +575,16 @@ public String toString() EHRService.get().registerHistoryDataSource(new org.labkey.api.ehr.history.DefaultAnimalRecordFlagDataSource(this)); EHRService.get().registerHistoryDataSource(new ONPRCClinicalRemarksDataSource(this)); - EHRService.get().registerMoreActionsButton(new CreateNecropsyRequestButton(this), "study", "encounters"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "encounters"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "tissue_samples"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "organ_weights"); - EHRService.get().registerOptionalClinicalHistoryResources(this); EHRService.get().registerLabworkType(new ONPRCUrinalysisLabworkType(this)); EHRService.get().registerLabworkType(new ONPRCiStatLabworkType(this)); + //R.Blasa 11-28-2016 EHRService.get().registerHistoryDataSource(new DefaultNHPTrainingDataSource(this)); - //R.Blasa 11-20-2019 EHRService.get().registerHistoryDataSource(new DefaultSustainedReleaseDatasource(this)); - - - - AdminLinkManager.getInstance().addListener((adminNavTree, container, user) -> - { - if (container.hasPermission(user, AdminPermission.class) && container.getActiveModules().contains(ONPRC_EHRModule.this)) - { - adminNavTree.addChild(new NavTree("EHR Admin Page", new ActionURL("onprc_ehr", "ehrAdmin", container))); - } - }); - } @Override From 1e477caebc450e712aa7d6fd228956f1fdf4143d Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 20:58:06 -0700 Subject: [PATCH 12/49] Merge from onprc19.1 r.65063, 65064, 65071, 65388 to 65398 --- onprc_billing/resources/etls/ogaSynch2020.xml | 46 +++ .../onprc_billing/LeaseFeeRates_Final.sql | 14 +- .../LeaseFeeReleaseAdjustment.sql | 8 + .../onprc_billing/LeaseFee_Demographics.sql | 31 +- .../onprc_billing/LeaseFee_LeaseType.sql | 181 ++++------- .../queries/onprc_billing/RateCalc.sql | 136 ++++++++ .../onprc_billing/leaseFeeRates_2020.sql | 4 +- .../leaseFeeRates_Final.query.xml | 151 +++++++++ .../onprc_billing/leasefee_rateData.sql | 236 +++----------- .../queries/onprc_billing/miscChargesFees.sql | 2 +- .../onprc_billing/miscChargesWithRates.sql | 2 +- .../queries/onprc_billing/ogaSourceOutPut.sql | 43 +++ .../sqlserver/onprc_billing-20.410-20.411.sql | 88 ++++++ .../onprc_billing/ONPRC_BillingModule.java | 2 +- .../resources/etls/HarvestToPrime_Process.xml | 10 + .../onprc_ehr/LabServiceRequest_Active.sql | 2 + onprc_ehr/resources/queries/study/Birth.js | 129 -------- .../queries/study/ClinpathRuns.query.xml | 136 ++++++++ .../queries/study/chemPivot.query.xml | 2 +- .../resources/queries/study/chemPivot.sql | 9 +- .../resources/queries/study/dualassigned.sql | 104 ++++++ .../queries/study/hematologyPivot.query.xml | 2 +- .../queries/study/hematologyPivot.sql | 14 +- .../scripts/onprc_ehr/onprc_triggers.js | 95 ++++++ .../data/sources/ClinpathRunsClientStore.js | 140 ++++++++ .../onprc_ehr/model/sources/labworkPanel.js | 23 ++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 48 ++- .../ColonyAlertsNotification.java | 299 +++++++++++++++++- .../query/ONPRC_EHRTriggerHelper.java | 6 +- 29 files changed, 1465 insertions(+), 498 deletions(-) create mode 100644 onprc_billing/resources/etls/ogaSynch2020.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/RateCalc.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/leaseFeeRates_Final.query.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/ogaSourceOutPut.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql create mode 100644 onprc_ehr/resources/queries/onprc_ehr/LabServiceRequest_Active.sql delete mode 100644 onprc_ehr/resources/queries/study/Birth.js create mode 100644 onprc_ehr/resources/queries/study/ClinpathRuns.query.xml create mode 100644 onprc_ehr/resources/queries/study/dualassigned.sql create mode 100644 onprc_ehr/resources/web/onprc_ehr/data/sources/ClinpathRunsClientStore.js diff --git a/onprc_billing/resources/etls/ogaSynch2020.xml b/onprc_billing/resources/etls/ogaSynch2020.xml new file mode 100644 index 000000000..8dc148a82 --- /dev/null +++ b/onprc_billing/resources/etls/ogaSynch2020.xml @@ -0,0 +1,46 @@ + + + + + + + + + OGASync2020 + + Copies OGA Data from external source to PRIME for PRocessing + + + + + + Import to OGA Sync in Prime + + + + + + + + + Runs a stored procedure to Update Transaction log based on OGA External Schema. + + + + + + + Runs a stored procedure Update the OGA Associated Datasets in Prime based on Transaction Log. + + + + + + + + + + + + + diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql index 6e83cf69b..159f2d300 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql @@ -1,3 +1,5 @@ +--2020/02/12 build + SELECT r.Id, r.date as BillingDate, r.enddate as ReleaseDate, @@ -17,7 +19,7 @@ Case When r.item = 'Lease Fee Adjustment' then a.leaseCharge1.name else null end as OriginalLeaseType, -a.leaseCharge2 as FinalLeaseType, +r.revisedChargeID as FinalLeaseType, r.AssignmentType as ChargeCategory, r.CalculatedRate as UnitCost, cr.unitCost as NIHRate, @@ -26,6 +28,8 @@ cr.unitCost as NIHRate, --case statement when dayeleaselength > 0 then dayleasr leanth else 1 as quantity case when r.DayLeaseLength> 0 then r.dayleaseLength + when r.researchowned = 'Yes' then 0 + when d.birthType = 'Born to Resource Dam' then 0 Else 1 End as Quantity, --Credit Alias Need to @@ -61,7 +65,9 @@ When d.creditResource is not Null then d.creditTo else ca.account End as CreditAccount, case - when r.DayLeaseLength> 0 then (r.dayleaseLength * r.CalculatedRate) + WHen r.releaseType = 'No Charge' then 0 + when r.researchOwned = 'Yes' then 0 + when r.DayLeaseLength > 0 and r.daylease = 'yes' then (r.dayleaseLength * r.CalculatedRate) when r.revisedrate is not null and r.revisedrate > r.CalculatedRate then (r.revisedRate - r.CalculatedRate) when r.revisedrate is not null and r.revisedrate < r.CalculatedRate then (r.CalculatedRate - r.RevisedRate) @@ -83,9 +89,7 @@ r.revisedRate --IS Assigned to Protocol at Time FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeRates_2020 r - left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeReleaseAdjustment a on a.id = r.id and a.date = r.date + left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeReleaseAdjustment a on a.id = r.id left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates cr on r.chargeID = cr.chargeID and (cr.startDate <= r.date and cr.enddate >= r.date or cr.enddate is null) left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.creditAccount ca on ca.chargeID = r.chargeID and (r.Date > ca.startDate and r.Date <= ca.enddate) - --left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.chargeRates cr on r.chargeID = cr.chargeID and (cr.startDate <= r.date and cr.enddate >= r.date or cr.enddate is null) - --left join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.LeaseFeeRates_CreditTo ct on r.chargeID = ct.chargeID and ct.id <= r.id and ct.assignmentDate = r.date Left outer join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.date = d.date and r.project = d.project \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql index 05f0de6da..a55bc8e42 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql @@ -29,6 +29,7 @@ a5.id as ESPFAnimal, (SELECT max(rowid) as rowid FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.chargeableItems ci WHERE ci.name = javaConstant('org.labkey.onprc_billing.ONPRC_BillingManager.LEASE_FEE_ADJUSTMENT') and ci.active = true) as chargeId, CASE when (fl.id Is Not Null) then 0 + when (d.researchOwned = 'yes') then 0 else 1 end as quantity, lf2.chargeId as leaseCharge1, @@ -36,6 +37,10 @@ lf.chargeId as leaseCharge2, a.objectid as sourceRecord, 'Adjustment - Automatic' as chargeCategory, 'Y' as isAdjustment, +Case + When a.id in (Select f.id from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.flags f where (f.id = a.id and f.flag.value = 'PI Purchased NHP' and f.enddate is Null)) then 'yes' + else 'No' + End as ResearchOwned, a.datefinalized, a.enddatefinalized @@ -78,6 +83,9 @@ Left JOIN Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study. and fl.flag.code = 4034 and (a.date >= fl.date and a.date <=COALESCE(fl.enddate,Now()) )) +LEFt join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFee_demographics d + on a.id = d.id + WHERE a.releaseCondition != a.projectedReleaseCondition and (A.id != A5.id or A5.id is Null) AND (a.enddatefinalized is not null) diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql index 77f72a263..c0c1d8623 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql @@ -48,6 +48,8 @@ end as AssignmentType, --determine if day lease - Case + WHen a.assigncondition <> a.projectedReleaseCondition then 'No' + WHen a.assigncondition <> a.ReleaseCondition then 'No' When (TimestampDiff('SQL_TSI_DAY',a.date,a.enddate) < 15 and TimestampDiff('SQL_TSI_DAY',a.date,a.enddate) >= 0) then 'Yes' When TimestampDiff('SQL_TSI_DAY',a.date,a.projectedRelease) < 0 then 'Bad Date Entry' When TimestampDiff('SQL_TSI_DAY',a.date,a.projectedRelease) < 15 then 'Yes' @@ -57,6 +59,8 @@ End as DayLease, --build in to handle bad code Case + WHen a.assigncondition <> a.projectedReleaseCondition then 1 + WHen a.assigncondition <> a.ReleaseCondition then 1 when a.enddate is not null and TimestampDiff('SQL_TSI_DAY',a.date,a.enddate) < 15 then TimestampDiff('SQL_TSI_DAY',a.date,a.enddate) when a.projectedRelease is not null and TimestampDiff('SQL_TSI_DAY',a.date,a.projectedRelease) < 15 and TimestampDiff('SQL_TSI_DAY',a.date,a.projectedRelease) >=0 then TimestampDiff('SQL_TSI_DAY',a.date,a.projectedRelease) Else Null @@ -65,21 +69,20 @@ Case --need to determine if this is a dual assignment so we can tag who receives the credit Case - when (Select Count(a2.project.name) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) > 2 then 'Over 2 Assignments' - when tmb.id is not null then 'TMB Dam' - when (Select Count(a2.project.name) from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) = 2 then - 'Dual Assigned' + When da.project is not null then 'Dual Assigned' End as MultipleAssignments, --(Select a2.project.name from study.assignment a2 where (a2.id = a.id and a.project <> a2.project and a2.enddate is null and a2.date <= a.date)) as DualAssignment, -Case - When da.project is not null and da.dualassignment = a.project then da.project.name - else null - End as CreditResource, -Case - When da.project is not null and da.dualassignment = a.project then da.project.account - else null - End as CreditTo, +---Case + -- When (da.project is not null and da.projectCategory = 'Resource') and da.dualassignment = a.project then da.project.name + -- else null + da.projectName as CreditResource, + da.project.Account as CreditTo, +--Case +-- When (da.project is not null and da.projectCategory = 'Resource') and da.dualassignment = a.project then da.project.account +-- else null + -- da.projectAccount as CreditTo, + a.date, @@ -110,8 +113,8 @@ FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assig left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.tmbBirth t on a.id = t.id left join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.birth_resourceDam d on a.id = d.id --left outer join study.tmbdam t on t.id = a.id.birth.dam -Left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.dualassigned da on da.id = a.id and (da.dualassignment = a.project - and (da.enddate is null or da.enddate > a.date) and (da.dualenddate is null or da.Dualenddate > a.date)) +Left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.dualassigned da on da.id = a.id and (da.dualassignment = a.project.project + and (da.enddate is null or da.enddate >= a.date) and (da.dualenddate is null or da.Dualenddate >= a.date)) Left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.tmbDam tmb on tmb.id = a.id and (tmb.date <= a.date and tmb.enddate >= a.date or tmb.endDate is Null) where a.datefinalized >= startDate and (a.datefinalized <= enddate or a.enddate is null) diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql index 11bbff8ae..3876e2a8d 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_LeaseType.sql @@ -1,151 +1,106 @@ -/* -Query Name: Leasefee_LeaseType -Purpose: The purpose of this query is to determine the Lease type based on the Conidtions defined in the Lease Type statement -Created by: Gary Jones -Dependency: onprc_billing.leasefee_demographics - study.birth - study.lease_ObeseInfant_HFDDam -Narrative: -Reading the data from LeaseFee_Demographics to assist in determine the lease type for billing processes -THere are 20 separate conditions that result in a lease fee being selected -??Why do I need the assignment table when the needed data is available from leaseFee-Demographics ---TODO Look at the Adjustments at time of Release -COndition Code Change -00Not if PI Owned] -Not if ESPF one use Animal -Obese - TMB - ESPF ---Update 2020-01-10 Changes ESPF to U42 Expanded SPF Lease so that will properly display ---2020-01-15 Update to handle TMB Adult Assignment - -*/ SELECT l.id, +l.researchOwned, +l.project, +l.alias, +l.ageatAssignment, +l.ageinYears, +l.AgeGroup, +l.BirthAssignment, +l.BirthType, +l.AssignmentType, +l.daylease, +Case + when l.dayleaseLength = 0 then 1 + else l.dayLeaseLength + end as DayLeaseLength, +l.multipleAssignments, +l.CreditResource, +l.creditTo, +l.date as AssignmentDate, +l.projectid, +l.projectedRelease, +l.enddate as ReleaseDate, +l.dateFinalized, +l.assignCondition, +l.projectedReleaseCondition, +l.releaseCondition, +l.releaseType, +l.remark, +l.faRate, +l.removesubsidy, +l.canRaiseFA, + +--this provides the recorded dam for the NHP assocatied to the assignment +b.dam, +da.project as DualAssigned, Case --Research Owned Animal -When l.researchowned = 'yes' then 'researchOwned' + When l.researchowned = 'yes' then 'researchOwned' --Adult Research Assignment P51 Animal (animal unassigned and adult) ----**Dual Assigned Obese JMac Control Infant Lease -When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and (l.id !=r.id or r.id is null) then 'Obese JMac Control Infant' + When l.id.age.ageinyears < 3 and da.projectname = '0622-01'and (l.id !=r.id or r.id is null) then 'Obese JMac Control Infant' ----**Dual Assigned Obese JMac WSD Infant Lease -When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' - - ---Adult Day Lease Condition Change for Research Assigned Adults - remove Age restriction -When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition = l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null ) then 'Day Lease Research Assignment P51 NHP NC' ---Adult Day L:ease No Condition Change -When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition != l.projectedReleaseCondition) and (da.project.name != '0833' or da.project.name is Null) then 'Day Lease Research Assignment P51 NHP Condition Change' - + When l.id.age.ageinyears < 3 and da.projectname = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' + --Adult Day Lease Condition Change for Research Assigned Adults - remove Age restriction + When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition = l.projectedReleaseCondition) and (da.projectname != '0833' or da.projectname is Null ) then 'Day Lease Research Assignment P51 NHP NC' + --Adult Day L:ease No Condition Change + When (l.id.age.ageinyears > 1 and l.dayLease = 'yes' and l.assignCondition != l.projectedReleaseCondition) and (da.projectname != '0833' or da.projectname is Null) then 'Day Lease Research Assignment P51 NHP Condition Change' --Dual assigned ESPF using different Chared Code -When da.project.Name = '0492-03' then 'U42 Expanded SPF Lease' +-- When da.projectName = '0492-03' then 'DualAssignedESPF' --Dual assigned TMB Male on Day Lease -When l.agegroup = 'Adult' and da.project.name = '0300' and l.dayLease = 'yes' then 'TMB Adult Day Lease' - - -/*********Dual Assigned TMB Dam */ -When l.MultipleAssignments = 'TMB Dam' then 'Animal Lease Fee -TMB' + When l.agegroup = 'Adult' and da.projectname = '0300' and l.dayLease = 'yes' then 'TMB Adult Day Lease' +--Dual assigned Obese Male Day Lease + When l.agegroup = 'Adult' and da.projectname = '0833' and l.dayLease = 'yes' then 'OBESE Adult Day Lease' --Full LEase P51 adult -When l.id.age.ageinyears > 1 and l.daylease <> 'yes' and (da.project.name <> '0833' or da.project.Name is Null) then 'Research Assignment P51 Adult' - + When l.id.age.ageinyears > 1 and l.daylease <> 'yes' and (da.projectname <> '0833' or da.projectName is Null) then 'Research Assignment P51 Adult' --**Dual Assigned TMB-Dam Assigned Use lease_TMB as Process -------------------------------------------------------------------------------------------------------- - -- For No charge Dam is Dual assigned to TMB and to the Project and Infant is assigned to the Project - THe lease for infant is built into the TMB Lease of the Dam -WHEN L.Birthtype = 'TMBResearchAssignment' then 'TMB No Charge' - + WHEN L.Birthtype = 'TMBResearchAssignment' then 'TMB No Charge' --**Dual Assigned TMB Dam Not Assigned ---------------------------------------------------------------------------------------------------------------------------- -- For this the INfant and Dam are not assigned to the same project and the dam is assigned to TMB -WHEN L.Birthtype = 'TMB DAm Not Assigned' then 'TMB Full P 51 Rate Lease' --- TMB Dam is TMB and is assigned to Research to produce infant --- When l.id in (Select d1.id from study.tmbdam d1 where d1.id = l.id and d1.date < l.date and l.enddate is Null) and l.project.Use_category = 'Research' --- then 'TMB Dam Research Assignment' + WHEN L.Birthtype = 'TMB DAm Not Assigned' then 'TMB Full P 51 Rate Lease' --Infant born to Resource Dam -When l.birthType = 'Born to Resource Dam' then l.birthType - + When l.birthType = 'Born to Resource Dam' then l.birthType +--handle Birth to resource and research at birth --handle it +/*********Dual Assigned ESPFTMB Birth */ + When da.projectName = '0492-03' then 'DualAssignedESPF' ----Dual Assigned Obese JMac Infant or Dam Day Lease = No condition Code CHanges - if change full lease ---need to change to also incldue if the damn is there -When da.project.name = '0622-01' and l.daylease = 'yes' then 'Obese 0622-01 Day Lease' + When da.projectname = '0622-01' and l.daylease = 'yes' then 'Obese 0622-01 Day Lease' ----**Dual Assigned Obese JMac Control Infant Lease -When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id !=r.id then 'Obese JMac Control Infant' + When l.id.age.ageinyears < 3 and da.projectname = '0622-01'and l.id !=r.id then 'Obese JMac Control Infant' ----**Dual Assigned Obese JMac WSD Infant Lease -When l.id.age.ageinyears < 3 and da.project.name = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' + When l.id.age.ageinyears < 3 and da.projectname = '0622-01'and l.id =r.id then 'Obese JMac WSD Infant' ----**Dual Assigned Obese Adult Day Lease -When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'yes' then 'OBESE Adult Day Lease' + When l.agegroup = 'adult' and da.projectname = '0833' and l.daylease = 'yes' then 'OBESE Adult Day Lease' ----**Dual Assigned Obese Adult Male Lease -When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) != 'Terminal' then 'OBESE Adult Male Lease' + When l.agegroup = 'adult' and da.projectname = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) != 'Terminal' then 'OBESE Adult Male Lease' ----Dual Assigned Obese Adult Male Terminal Lease -When l.agegroup = 'adult' and da.project.name = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) = 'Terminal' then 'OBESE Adult Terminal Leasel' + When l.agegroup = 'adult' and da.projectname = '0833' and l.daylease = 'no' and Cast(l.projectedReleaseCondition as Varchar(20)) = 'Terminal' then 'OBESE Adult Terminal Leasel' --when Adult Animal Assigned to Research project ---when l.agegroup = 'adult' and da.project ='0300' then 'Aninal Lease Fee -TMB' + when l.agegroup = 'adult' and da.project ='0300' then 'Aninal Lease Fee -TMB' --Infant Research Assignment P51 Animal Day Lease ------------------------------------------------------------------------------------------------------- -When l.id.age.ageinyears < 1 and l.daylease = 'yes' then 'Day Lease Research Assignment P51 Infant' - + When l.id.age.ageinyears < 1 and l.daylease = 'yes' then 'Day Lease Research Assignment P51 Infant' --Infant Research Assignment P51 Animal------------------------------------------------------------------------------------------------------- -When l.ageatAssignment < 1 then 'Research Assignment P51 Infant' - - - + When l.ageatAssignment < 1 then 'Research Assignment P51 Infant' Else 'UnDeteremined' End As LeaseType, -Case +/*Case --Dual Assigned 0492-02 - When da.project.name = '0492-02' then 'Dual Assigned U42' + When da.projectname = '0492-02' then 'Dual Assigned U42' --Dual Assigned 0492-45 - When da.project.name = '0492-45' then 'Dual Assigned JMR' + When da.projectname = '0492-45' then 'Dual Assigned JMR' --Dual Assigned 0689 - When da.project.name = '0689' then 'Dual Assigned IDR Orphanage' + When da.projectname = '0689' then 'Dual Assigned IDR Orphanage' --Dual Assigned 0456 - When da.project.name = '0456' then 'Dual Assigned Aging' -When da.project.Name = '0492-03' then 'DualAssignedESPF' + When da.projectname = '0456' then 'Dual Assigned Aging' +When da.projectName = '0492-03' then 'DualAssignedESPF' else 'P-51' - ENd as CreditTo, +*/ - - -l.date as AssignmentDate, -l.projectedRelease, -l.enddate as ReleaseDate, -l.daylease, -Case - when l.dayleaseLength = 0 then 1 - else l.dayLeaseLength - end as DayLeaseLength, -l.project, ---this provides the recorded dam for the NHP assocatied to the assignment -b.dam, ---Need to determine the assignment of the dam at the time of the assignment it the lease is at the time of birth -----Use the value from leasefee Demograpbhics to determine if the lease being reviewed is at the time of the animal birth -----If the assignment is at the time of the animal birth then determine who the dam was and what was the Dam assignment at the time of birth ---Case - --WHen l.birthassignment = 'yes' then --'yes' - --then - --determine if mom is a resource dam - -- (Select g.groupID.name from study.animal_Group_Members g where g.id = (Select Dam from study.birth b1 where b1.id = l.id) and g.enddate is null) - --Else 'Non Birth Lease' - - ---End as ResourceBirth, ---(Select g.groupID.name from study.animal_Group_Members g where g.id = (Select Dam from study.birth b1 where b1.id = a.id) and g.enddate is null) as ResourceDamBirth, - ---need age at time of assignment this will come from LEaseFee_Demographics -l.ageatAssignment, -l.AgeGroup, -l.BirthAssignment, -l.BirthType, -l.AssignmentType, -da.project as DualAssigned, - -l.assignCondition, -l.projectedReleaseCondition, -l.releaseCondition, -l.releaseType, -l.remark, -l.alias, -l.faRate, -l.removesubsidy, -l.canRaiseFA, -l.project.project as projectID FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_demographics l left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.birth b on l.id = b.id left outer join Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.lease_ObeseInfant_HFDDam R on l.id = r.id diff --git a/onprc_billing/resources/queries/onprc_billing/RateCalc.sql b/onprc_billing/resources/queries/onprc_billing/RateCalc.sql new file mode 100644 index 000000000..7a4943a84 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/RateCalc.sql @@ -0,0 +1,136 @@ +USE [Labkey] +GO +/****** Object: UserDefinedFunction [onprc_ehr].[RateCalc] Script Date: 2/5/2020 2:39:01 PM +This is the rate calc function from SQL +2020/2/5 update to fix issue with no Subsidy value being populated + +******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +ALTER FUNCTION [onprc_ehr].[RateCalc] +--ALTER FUNCTION [onprc_ehr].[RateCalc] +( + @alias varchar(20), + @chargeId float, + @project float, + @startDate date, + @baseSubsidyVal float +) + +RETURNS float +AS +BEGIN + Declare @unitCostVal float, + @projectExemption float, + @projectMultipler float, + @unitCost float, + @NonOGAAlias varchar(20), + @blankAliasType varchar(20), + @baseSubsidy float, + @subsidy float, + @faRate float, + @removeSubsidy smallInt, + @aliasRaiseFA smallInt, + @chargeRaiseFA smallInt + + + --initiate Variables + --determine if there is a project level exemption + --the base subsidy is defined as a gloabl variable in the Labkey Java Code in onprc_ehr.java and if a change in the base rate is requested, the data needs to be updated in each position + Set @baseSubsidyVal = .47 + Set @basesubsidy = .47 + Set @unitCost = 1000 + Set @subsidy = @baseSubsidyVal + Set @projectExemption = (Select cr.unitcost From onprc_billing.chargeRateExemptions cr + Where cr.chargeId = @chargeId + and cr.project = @project + and cr.startDate < @startDate + and ((@startDate <= cr.endDate) or (cr.enddate is null))) + + --determine if there is a project level multiplier -- onprc_billing.projectMultipler + --verified the query + Set @projectMultipler = (Select pm.multiplier From onprc_billing.projectMultipliers pm + Where pm.account = @alias + and pm.startdate <= @startDate + and ((pm.enddate >= @startDate) or (pm.enddate is Null))) + + + --determine if the alias is a non oga rate --onprc_billing.aliases --category column + --verified query + Set @NonOGAAlias = (Select a.category From onprc_billing.aliases a + Where a.alias = @alias + and (a.budgetStartDate < @startDate and a.budgetEndDate > @startDate)) + + ----determine if Alias Type is Blank + ----verified query + Set @blankAliasType = (Select a.aliasType From onprc_billing.aliases a + Where a.alias = @alias + and (a.budgetStartDate < @startDate and a.budgetEndDate > @startDate)) + + ----determine if remove subsidy if true + ----verified query + Set @removeSubsidy = (Select t.removeSubsidy From onprc_billing.aliases a join onprc_billing.aliasTypes t on a.aliasType = t.aliasType + Where a.alias = @alias + and (a.budgetStartDate < @startDate and a.budgetEndDate > @startDate)) + + ----determine if raise F&A is True for Charge Rate --Need to set date parameters on most of these + ----Need to lock down date range + Set @chargeRaiseFA = (Select c.canRaiseFA From onprc_billing.chargeableItems c join onprc_billing.chargeRates cr on c.rowId = cr.chargeId + Where cr.chargeId = @chargeId + and (cr.StartDate < @startDate and cr.EndDate > @startDate)) + + ----determine if rate F&A is true for alias + Set @aliasRaiseFA = (Select t.canRaiseFA From onprc_billing.aliases a join onprc_billing.aliasTypes t on a.aliasType = t.aliasType + Where a.alias = @alias + and (a.budgetStartDate < @startDate and a.budgetEndDate > @startDate)) + + ----get FA Rate for Alias + Set @faRate = (Select a.faRate From onprc_billing.aliases a + Where a.alias = @alias + and (a.budgetStartDate < @startDate and a.budgetEndDate > @startDate)) + + --determine unit cost + --if it retunrs null there is no charge rate + Set @unitCost = (Select r.unitcost From onprc_billing.chargeRates r + Where r.chargeID = @chargeId + and r.startDate <= @startDate + and ((r.enddate >= @startDate) or r.enddate Is Null)) + + --determine Unit Cost + Select @unitCostVal = + + Case + --returns unit cost when there is an exemption at the project level + When @projectExemption is not null then @projectExemption + --return value for a charge that has a pm multiplier + When @projectMultipler is not null then @projectMultipler * @unitCost + ------ --where there is no unit cost listed return null + When @unitCost is null then null + --where the alias type is not OGA charge NIH Rate + When @NonOGAAlias is not null and @NonOGAAlias != 'OGA' then @unitCost + ------when alias type is not known then return null + When @blankAliasType is null then null + + When (@removeSubsidy = 1 AND (@aliasRaiseFA = 1 AND @chargeRaiseFA = 1)) + THEN ((@unitCost / (1 - COALESCE(@subsidy, 0))) * (CASE WHEN (@faRate IS NOT NULL AND @faRate < @baseSubsidy) THEN (1 + @baseSubsidy / (1 + @faRate)) ELSE 1 END)) + + When (@removeSubsidy = 1 AND @aliasRaiseFA = 0) + THEN (@unitCost / (1 - COALESCE(@subsidy, 0))) + + + When (@removeSubsidy = 0 AND (@aliasRaiseFA = 1 AND @chargeRaiseFA = 1)) + Then (@unitCost * (CASE WHEN (@faRate IS NOT NULL AND @faRate = 0) THEN (1 + @Subsidy / (1 + @faRate)) ELSE 1 END)) + + When (@removeSubsidy = 0 AND (@aliasRaiseFA = 1 AND @chargeRaiseFA = 1)) + Then (@unitCost * (CASE WHEN (@faRate IS NOT NULL AND @faRate < @Subsidy) THEN (1 + @Subsidy / (1 + @faRate)) ELSE 1 END)) + + Else @unitCost + END + + --return @unitCost + return @unitCostVal--@projectExemption + +End diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql index c8b7ccc23..b789728c6 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql @@ -37,7 +37,7 @@ SELECT d.Id, r.exemptionRate, r.Multiplier, r.subsidy, - RateCalc(r.AliasAtTime,r.chargeID,d.project,d.Date,d.farate) as CalculatedRate, + RateCalc(r.AliasAtTime,r.chargeID,d.project,d.Date,.4) as CalculatedRate, null as revisedRate, r.revisedChargeID, r.revisedSubsidy @@ -52,7 +52,7 @@ union select a.id, 'automatic_adjustment' as AssignmentType, - '' as researchOwned, + a.researchowned, a.projectID, --intege a.project.name as CenterProject, a.alias, diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_Final.query.xml b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_Final.query.xml new file mode 100644 index 000000000..b74ac460f --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_Final.query.xml @@ -0,0 +1,151 @@ + + + + + Lease Fee Charges + org.labkey.ehr.table.DefaultEHRCustomizer + + + + ehr + project + project + + + + + onprc_billing_public + aliases + alias + + + + Investigator + true + + onprc_ehr + investigators + rowid + lastName + + + + + ehr + tasks + taskid + rowid + + + + Charge + + onprc_billing_public + chargeableItems + rowid + + + + + onprc_billing_public + chargeableItems + rowid + + + + + onprc_billing_public + chargeableItems + rowid + + + + Is Rate Exemption? + + + Unit Cost + $###,##0.00 + + + Total Cost + $###,##0.00 + + + Credit Alias + + + true + + + true + + + true + + + Lacks Unit Cost? + true + + + Rate Id + true + /query/executeQuery.view?schemaName=onprc_billing&query.queryName=chargeRates&query.rowid~eq=${rateid} + + + Exemption Id + true + /query/executeQuery.view?schemaName=onprc_billing&query.queryName=chargeRateExemptions&query.rowid~eq=${exemptionId} + + + true + + + Is Manually Entered? + + + Is Adjustment/Reversal? + + + Missing Alias? + + + Missing FAID? + + + Expired Alias? + + + Alias Accepting Charges? + + + >45 Days Old? + + + Unit Cost, Based On Projected Release + true + + + NIH Rate, Based On Projected Release + true + + + Adjustment Unit Cost, Based On Projected Release + true + + + Adjustment NIH Rate, Based On Projected Release + true + + + Adjustment Unit Cost, Based On Actual Release + true + + + Adjustment NIH Rate, Based On Actual Release + true + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql b/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql index 5595bab35..f3422d8b6 100644 --- a/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql +++ b/onprc_billing/resources/queries/onprc_billing/leasefee_rateData.sql @@ -1,119 +1,3 @@ ---this returns day lease for adults ---updated 6/7/2019 correction of previous lease lookup ---2020-01-10 Updae to change the ESPF top correct Value --- resolved issue to insura all data sources use Subsstitute Path -Select -l.id, -l.project.name as CenterProject, -l.project.project as ProjectID, -l.alias, -l.leasetype, -l.assignmentdate, -l.assignCondition.code, -l.projectedReleaseCondition.code as ProjectedReleaseCode, -Cast(l.ageAtAssignment as Integer) as AssignmentAge, -Case - When l.leasetype = lf.chargeID.name then lf.chargeid - else Null - End as chargeId, -Null as RevisedChargeID, -l.dayleaselength as quantity - - - - -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l - JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( - - l.Leasetype = lf.chargeId.Name - AND lf.active = true) -where l.daylease <> 'yes' and l.leasetype != 'U42 Expanded SPF Lease' - -UNION - ---this returns ESPF DUal assigned animals -Select -l.id, -l.project.name as CenterProject, -l.project.project as ProjectID, -l.alias, -l.leasetype, -l.assignmentdate, -l.assignCondition.code, -l.projectedReleaseCondition.code as ProjectedReleaseCode, -Cast(l.ageAtAssignment as Integer) as AssignmentAge, -Case - When l.leasetype = 'U42 Expanded SPF Lease' then lf.chargeID - else Null - End as chargeId, -Null as RevisedChargeID, -1 as quantity - - - -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l JOIN - Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( - - l.Leasetype = lf.chargeId.Name - AND lf.active = true) -where l.daylease <> 'yes' - -UNION - -SELECT l.id, -l.project.name as CenterProject, -l.project.project as ProjectID, -l.alias, -l.leasetype, -l.assignmentdate, -l.assignCondition.code, - -l.projectedReleaseCondition.code as ProjectedReleaseCode, -Cast(l.ageAtAssignment as Integer) as AssignmentAge, -lf.chargeId, -Null as RevisedChargeID, - -1 as quantity - -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l - JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( - lf.chargeId.Name = 'Animal Lease Fee - TMB' and lf.active = true) - -where (l.leasetype = 'Animal Lease Fee -TMB') and l.daylease <> 'yes' - - -UNION - -SELECT l.id, -l.project.name as CenterProject, -l.project.project as ProjectID, -l.alias, -l.leasetype, -l.assignmentdate, -l.assignCondition.code, - -l.projectedReleaseCondition.code as ProjectedReleaseCode, -Cast(l.ageAtAssignment as Integer) as AssignmentAge, -lf.chargeId, -Null as RevisedChargeID, - -1 as quantity - -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l - left outer JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( - - lf.assignCondition = l.assignCondition.code - AND lf.releaseCondition = l.projectedReleaseCondition.code - AND (Cast(l.ageAtAssignment as Integer) >= lf.minAge OR lf.minAge IS NULL) - AND (Cast(l.ageAtAssignment as Integer) < lf.maxAge OR lf.maxAge IS NULL) - AND lf.active = true) - -where (l.leasetype = 'Research Assignment P51 Adult') and l.daylease <> 'yes' - -UNION - - ---day lease no condition change SELECT l.id, l.project.name as CenterProject, l.project.project as ProjectID, @@ -125,92 +9,44 @@ l.assignCondition.code, l.projectedReleaseCondition.code as ProjectedReleaseCode, Cast(l.ageAtAssignment as Integer) as AssignmentAge, Case - when l.daylease = 'yes' then '90' -end as ChargeID, -Null as RevisedChargeID, -l.dayleaselength as Quantity - -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l -where l.daylease = 'yes' and l.leasetype <> 'Day Lease Research Assignment P51 NHP Condition Change' - -UNION - - ---day lease condition change -SELECT l.id, -l.project.name as CenterProject, -l.project.project as ProjectID, -l.alias, -l.leasetype, -l.assignmentdate, -l.assignCondition.code, - -l.projectedReleaseCondition.code as ProjectedReleaseCode, -Cast(l.ageAtAssignment as Integer) as AssignmentAge, -lf.ChargeID, -Null as RevisedChargeID, - -1 as Quantity - -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l - left outer JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( - - lf.assignCondition = l.assignCondition.code - AND lf.releaseCondition = l.ReleaseCondition.code - AND (Cast(l.ageAtAssignment as Integer) >= lf.minAge OR lf.minAge IS NULL) - AND (Cast(l.ageAtAssignment as Integer) < lf.maxAge OR lf.maxAge IS NULL) - AND lf.active = true) - -where l.daylease = 'yes' and l.leasetype = 'Day Lease Research Assignment P51 NHP Condition Change' - - -UNION - -SELECT l.id, -l.project.name as CenterProject, -l.project.project as ProjectID, -l.alias, -l.leasetype, -l.assignmentdate, -l.assignCondition.code, -l.projectedReleaseCondition.code as ProjectedReleaseCode, -Cast(l.ageAtAssignment as Integer) as AssignmentAge, -Case - when l.leasetype = 'Research Assignment P51 Infant' then lf.chargeId -end as ChargeID, + when (l.leasetype = 'U42 Expanded SPF Lease' and l.daylease <> 'yes') then 5348 + When (l.leaseType = 'Obese 0622-01 Day Lease' and l.leasetype = lf.chargeID.name) then 5367 + When (l.leaseType = 'Obese JMac Control Infant' and l.daylease <> 'yes' and l.leasetype = lf.chargeID.name) then 5372 + When (l.leaseType = 'Obese JMac WSD Infant' and l.daylease <> 'yes' and l.leasetype = lf.chargeID.name) then 5371 + When (l.leaseType = 'OBESE Adult Male Lease' and l.daylease <> 'yes' and l.leasetype = lf.chargeID.name) then 5368 + When (l.leaseType = 'OBESE Adult Terminal Leasel' and l.daylease <> 'yes' and l.leasetype = lf.chargeID.name) then 5369 + When (l.leaseType = 'OBESE Adult Day Lease' and l.leasetype = lf.chargeID.name) then 5367 + When (l.leaseType = 'Day Lease Research Assignment P51 NHP Condition Change' and l.leasetype = lf.chargeID.name) then 9999 + When (l.leaseType = 'Day Lease Research Assignment P51 NHP NC' ) then 90 + When (l.leaseType = 'DualAssignedESPF' and l.daylease <> 'yes' and l.leasetype = lf.chargeID.name) then null + when (l.leasetype = 'Animal Lease Fee - TMB') and l.daylease <> 'yes' then 1552 + + When (l.leaseType = 'TMB Adult Day Lease' and l.leasetype = lf.chargeID.name) then 90 + When (l.leaseType = 'TMB No Charge' and l.leasetype = lf.chargeID.name) then Null + When (l.leaseType = 'TMB Full P 51 Rate Lease' and l.leasetype = lf.chargeID.name) then + (Select lf1.ChargeID from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf1 + where lf1.assignCondition = l.assignCondition + AND lf1.releaseCondition = l.projectedReleaseCondition + AND (l.ageAtAssignment >= lf1.minAge OR lf1.minAge IS NULL) + AND (l.ageAtAssignment < lf1.maxAge OR lf1.maxAge IS NULL) + AND lf1.active = true) + when (l.leasetype like 'Research Assignment P51 %' and l.daylease <> 'yes') then + (Select lf2.ChargeID from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf2 + where lf2.assignCondition = l.assignCondition + AND lf2.releaseCondition = l.projectedReleaseCondition + AND (l.ageAtAssignment >= lf2.minAge OR lf2.minAge IS NULL) + AND (l.ageAtAssignment < lf2.maxAge OR lf2.maxAge IS NULL) + AND lf2.active = true) + + + When (l.leaseType = 'Born to Resource Dam' ) then Null + Else Null + End as chargeID, +--lf.chargeId, Null as RevisedChargeID, 1 as quantity -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l - left outer JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf ON ( - - lf.assignCondition = l.assignCondition.code - AND lf.releaseCondition = l.projectedReleaseCondition.code - AND (Cast(l.ageAtAssignment as Integer) >= lf.minAge OR lf.minAge IS NULL) - AND (Cast(l.ageAtAssignment as Integer) < lf.maxAge OR lf.maxAge IS NULL) - AND lf.active = true) - -where (l.leasetype = 'Research Assignment P51 Infant') and l.daylease <> 'yes' - ---deals with Release adjustmnents -UNION - -Select -r.id, -r.project.name as CenterProject, -r.project.project as ProjectID, -r.alias, -'Adjustment-Automatic' as LeaseType, -r.date, -r.assignCondition, -Null as ProjectedReleaseCondition, -r.ageatTime, -r.leasecharge2 as originalChargeID, -r.leasecharge1 as revisedChargeID, - -1 as quantity - - -from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeReleaseAdjustment r \ No newline at end of file +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_Billing.leaseFee_LeaseType l left outer join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf on l.leaseType = lf.chargeID.name \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql index 49f26dcf3..feac4d44d 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesFees.sql @@ -82,7 +82,7 @@ LEFT JOIN onprc_billing_public.projectAccountHistory aliasAtTime ON ( ) LEFT JOIN onprc_billing_public.aliases alias ON ( - aliasAtTime.account = alias.alias + aliasAtTime.account = alias.alias and alias.datedisabled is null ) LEFT JOIN onprc_billing_public.projectMultipliers pm ON ( diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql index 5ab13fd93..ffe18c7fd 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql @@ -157,7 +157,7 @@ LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer' ) LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.aliases alias ON ( - alias.alias = COALESCE(p.debitedaccount, aliasAtTime.account) + alias.alias = COALESCE(p.debitedaccount, aliasAtTime.account) and alias.dateDisabled is Null ) LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing_public.projectMultipliers pm ON ( diff --git a/onprc_billing/resources/queries/onprc_billing/ogaSourceOutPut.sql b/onprc_billing/resources/queries/onprc_billing/ogaSourceOutPut.sql new file mode 100644 index 000000000..2db3e890e --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/ogaSourceOutPut.sql @@ -0,0 +1,43 @@ +SELECT ZGMS_PRIM_ALL_V.ADFM_EMP_NUM, +ZGMS_PRIM_ALL_V.ADFM_FULL_NAME, +ZGMS_PRIM_ALL_V.ADFM_LAST_NAME, +ZGMS_PRIM_ALL_V.ADFM_FIRST_NAME, +ZGMS_PRIM_ALL_V.PI_EMP_NUM, +ZGMS_PRIM_ALL_V.PI_FULL_NAME, +ZGMS_PRIM_ALL_V.PI_LAST_NAME, +ZGMS_PRIM_ALL_V.PI_FIRST_NAME, +ZGMS_PRIM_ALL_V.PDFM_EMP_NUM, +ZGMS_PRIM_ALL_V.PDFM_FULL_NAME, +ZGMS_PRIM_ALL_V.PDFM_LAST_NAME, +ZGMS_PRIM_ALL_V.PDFM_FIRST_NAME, +ZGMS_PRIM_ALL_V.AGENCY_AWARD_NUMBER, +ZGMS_PRIM_ALL_V.OGA_AWARD_NUMBER, +ZGMS_PRIM_ALL_V.OGA_AWARD_TYPE, +ZGMS_PRIM_ALL_V.OGA_PROJECT_NUMBER, +ZGMS_PRIM_ALL_V.OGA_PROJECT_NAME, +ZGMS_PRIM_ALL_V.ALIAS, +ZGMS_PRIM_ALL_V.ALIAS_ENABLED_FLAG, +ZGMS_PRIM_ALL_V.PROJECT_DESCRIPTION, +ZGMS_PRIM_ALL_V.APPLICATION_TYPE, +ZGMS_PRIM_ALL_V.APPLICATION_TYPE_DESCRIPTION, +ZGMS_PRIM_ALL_V.ACTIVITY_TYPE, +ZGMS_PRIM_ALL_V.ACTIVITY_TYPE_DESCRIPTION, +ZGMS_PRIM_ALL_V.AWARD_NUMBER, +ZGMS_PRIM_ALL_V.AWARD_SUFFIX, +ZGMS_PRIM_ALL_V.ORG, +ZGMS_PRIM_ALL_V.CURRENT_BUDGET_START_DATE, +ZGMS_PRIM_ALL_V.CURRENT_BUDGET_END_DATE, +ZGMS_PRIM_ALL_V.PROJECT_TITLE, +ZGMS_PRIM_ALL_V.PPQ_CODE, +ZGMS_PRIM_ALL_V.PPQ_DATE, +ZGMS_PRIM_ALL_V.IACUC_NUMBER, +ZGMS_PRIM_ALL_V.AWARD_STATUS, +ZGMS_PRIM_ALL_V.PROJECT_STATUS, +ZGMS_PRIM_ALL_V.AWARD_ID, +ZGMS_PRIM_ALL_V.PROJECT_ID, +ZGMS_PRIM_ALL_V.BURDEN_SCHEDULE, +ZGMS_PRIM_ALL_V.BURDEN_RATE, +Cast(ZGMS_PRIM_ALL_V.BURDEN_RATE as VARCHAR(20)) as faRate, +ZGMS_PRIM_ALL_V.FUNDING_SOURCE_NUMBER, +ZGMS_PRIM_ALL_V.FUNDING_SOURCE_NAME +FROM ZGMS_PRIM_ALL_V \ No newline at end of file diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql new file mode 100644 index 000000000..31248e562 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015-2016 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +-- ================================================ +-- Template generated from Template Explorer using: +-- Create Procedure (New Menu).SQL +-- +-- Use the Specify Values for Template Parameters +-- command (Ctrl-Shift-M) to fill in the parameter +-- values below. +-- +-- This block of comments will not be included in +-- the definition of the procedure. +-- ================================================ +USE Labkey +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ============================================= +-- Author: Jonesga@phsu.edu +-- Create date: 2020/4/11 +-- Description: Process to clean the onprc_billing.aliases dataset to only pertient +-- ============================================= +IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'AliasCleanup202004') + DROP PROCEDURE ALIASCleanup202004 +GO +CREATE PROCEDURE onprc_billing.AliasCleanup202004 + +AS +BEGIN + --Handles active non OGA Aliases + Update a + Set a.projectStatus = 'Active',a.comments = 'In Use - Non ONPRC Alias', a.category = 'OHSU GL' +--Se[onprc_billing].[OGA_RemoveRecords]ect a.Alias,p.account -- update the category to + from onprc_billing.aliases a join onprc_billing.projectAccountHistory p on p.account = a.alias + where p.enddate > = GetDate() and a.alias Not Like '9%' + +-- updates the alias dataset setting end date and comment for disabled aliases + Update a + Set dateDisabled = '4/1/2020', Comments = 'Alias Disabled' + from onprc_billing.aliases a + where aliasEnabled = 'N' + + Update a1 + set a1.projectStatus = 'Non Active GL', a1.aliasEnabled = 'n', a1.datedisabled = GetDate(), a1.comments = 'GL Alias Not Active entered Previously' + + from onprc_billing.aliases a1 left outer join onprc_billing.projectAccountHistory p on p.account = a1.alias + where a1.alias not like '9%' and (a1.comments != 'In Use - Non ONPRC Alias' or a1.comments is null) + + Update a2 + Set a2.dateDisabled = GetDate(), comments = 'Expired Alias', aliasEnabled = 'n' +--select a1.alias,a1.budgetEndDate + from onprc_billing.aliases a2 + where a2.budgetEndDate <=GetDate() + + Update a4 + set dateDisabled = GetDate(), comments = 'Grant Closed', projectStatus = 'Grant Closed', aliasEnabled = 'N' +--Select a4.alias,s.[PROJECT STATUS],a4.projectStatus + from onprc_billing.aliases a4 left Outer join onprc_billing.ogaSynch s on Cast(a4.alias as varchar(50)) = Cast(s.[alias] as VarChar(50)) + where a4.dateDisabled is null and a4.projectstatus in ('Archived','Closed','IM PURGEd') +--Remove Records not associated with ONPRC + DELETE FROM onprc_billing.aliases + where alias in (Select a.alias + from onprc_billing.aliases a left outer join onprc_billing.projectAccountHistory p on a.alias = p.account + where p.account is null and a.dateDisabled is not null) + --Update the existing data to add PPQ, ORG PPQ Date to Existing Aliases +--Update a10 +--Set A10. = s.ORG, a10.PPQNumber = s.[PPQ CODE], a10.PPQDate = s.[PPQ DATE] +--from onprc_billing.aliases a10 left Outer join onprc_billing.ogaSynch s on Cast(a10.alias as varchar(50)) = Cast(s.[alias] as VarChar(50)) +--where a10.Org is null +END +GO + + + diff --git a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java index 372b747f6..a5557ca1f 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java +++ b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java @@ -80,7 +80,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 19.408; + return 19.411; } @Override diff --git a/onprc_ehr/resources/etls/HarvestToPrime_Process.xml b/onprc_ehr/resources/etls/HarvestToPrime_Process.xml index c95ca9040..d8a0ee0bc 100644 --- a/onprc_ehr/resources/etls/HarvestToPrime_Process.xml +++ b/onprc_ehr/resources/etls/HarvestToPrime_Process.xml @@ -56,6 +56,16 @@ + + + Transfer to EHR Requests + + + + + + + diff --git a/onprc_ehr/resources/queries/onprc_ehr/LabServiceRequest_Active.sql b/onprc_ehr/resources/queries/onprc_ehr/LabServiceRequest_Active.sql new file mode 100644 index 000000000..6b849e87f --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/LabServiceRequest_Active.sql @@ -0,0 +1,2 @@ +select * from ehr_Lookups.labwork_services +where datedisabled is null diff --git a/onprc_ehr/resources/queries/study/Birth.js b/onprc_ehr/resources/queries/study/Birth.js deleted file mode 100644 index d937acc20..000000000 --- a/onprc_ehr/resources/queries/study/Birth.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2010-2014 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -//Created 3-3-2017 R.Blasa -require("ehr/triggers").initScript(this); - -function onInit(event, helper){ - helper.setScriptOptions({ - allowAnyId: true, - requiresStatusRecalc: true, - allowDeadIds: true, - skipIdFormatCheck: true, - skipHousingCheck: true, - announceAllModifiedParticipants: true - }); - - helper.decodeExtraContextProperty('birthsInTransaction'); -} - -function onUpsert(helper, scriptErrors, row, oldRow){ - if (row.weight && !row.wdate){ - EHR.Server.Utils.addError(scriptErrors, 'wdate', 'This field is required when supplying a weight', 'WARN'); - } - - if (!row.weight && row.wdate){ - EHR.Server.Utils.addError(scriptErrors, 'weight', 'This field is required when supplying a weight date', 'WARN'); - } - - // the highest error this can produce is WARN. therefore skip this check if we would ignore it anyway in order to save the overhead. - // this would normally occur when finalizing a form - if (!helper.isETL() && row.Id && row.weight && row.species && EHR.Server.Utils.shouldIncludeError('WARN', helper.getErrorThreshold(), helper)){ - var msg = helper.getJavaHelper().verifyWeightRange(row.Id, row.weight, row.species); - if (msg != null){ - EHR.Server.Utils.addError(scriptErrors, 'weight', msg, 'WARN'); - } - } -} - -EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'Birth', function(scriptErrors, helper, row, oldRow) -{ - // skip normal birth records process when birth condition has a value of Fetus - if (row.Id && row.birth_condition == 'Fetus - Prenatal') - { - var obj = { - Id: row.Id, - birth: row.date, - date: row.date, - calculated_status: 'Fetus' - }; - - - helper.getJavaHelper().createDemographicsRecord(row.Id, obj); - } - - else - { - var isLiving = EHR.Server.Utils.isLiveBirth(row.birth_condition); - if (isLiving) - { - helper.registerLiveBirth(row.Id, row.date); - } - - if (!helper.isETL()) - { - //if a weight is provided, we insert into the weight table: - if (row.weight && row.wdate) - { - helper.getJavaHelper().insertWeight(row.Id, row.wdate, row.weight); - } - - //if room provided, we insert into housing. if this animal already has an active housing record, skip - //Modified: 5-4-2018 R. Blasa Housing (This being handled by onprc_trigger.js) - // if (row.room && row.Id && row.date) - // { - // console.log("Birth js file") - // // helper.getJavaHelper().createHousingRecord(row.Id, row.date, (isLiving ? null : row.date), row.room, (row.cage || null),null); - // } - - if (!helper.isGeneratedByServer()) - { - var obj = { - Id: row.Id, - gender: row.gender, - dam: row.dam, - sire: row.sire, - origin: row.origin, - birth: row.date, - date: row.date, - calculated_status: isLiving ? 'Alive' : 'Dead' - - }; - - //NOTE: the follow is designed to allow the table to either have physical columns for species/origin, or do display the demographics values. in the latter case, editing the form field will act to update the demographics record - if (row.species || row['Id/demographics/species']) - { - obj.species = row.species || row['Id/demographics/species']; - } - - if (row.geographic_origin || row['Id/demographics/geographic_origin']) - { - obj.geographic_origin = row.geographic_origin || row['Id/demographics/geographic_origin']; - } - - //find dam, if provided - if (row.dam && !obj.geographic_origin) - { - obj.geographic_origin = helper.getJavaHelper().getGeographicOrigin(row.dam); - } - - if (row.dam && !obj.species) - { - obj.species = helper.getJavaHelper().getSpecies(row.dam); - } - - if (!isLiving) - { - obj.death = row.date; - } - - //if not already present, we insert into demographics - helper.getJavaHelper().createDemographicsRecord(row.Id, obj); - } - } - } - -}); \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/ClinpathRuns.query.xml b/onprc_ehr/resources/queries/study/ClinpathRuns.query.xml new file mode 100644 index 000000000..b7ec57b91 --- /dev/null +++ b/onprc_ehr/resources/queries/study/ClinpathRuns.query.xml @@ -0,0 +1,136 @@ + + + + + /ehr/clinpathDetails.view?lsid=${lsid}&objectid=${objectid} + + + + + servicerequested + + + + + + Collection Date + + + + + + Service Requested + + ehr_lookups + Labwork_services + servicename + + + + Charge Unit + + ehr_lookups + labworkChargeType + value + + + + Sample Type + + ehr_lookups + clinpath_sampletype + value + + + + Tissue + + ehr_lookups + snomed + code + + + + Sample Quantity + true + + + Quantity Units + true + + + Sample Units + true + + + Collected By + + + Collection Method + + ehr_lookups + clinpath_collection_method + value + + + + Method + + + Remark + + + Category + + ehr_lookups + clinpath_types + value + + + + + Special Instructions + textarea + + + Reviewed By + + + Date Reviewed + + + true + + + true + + + true + + + true + + + true + + + true + + + Units + + + Clinical Remark + + + Sample Id + true + + + Condition + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/chemPivot.query.xml b/onprc_ehr/resources/queries/study/chemPivot.query.xml index cbe469f70..e52ee4ce3 100644 --- a/onprc_ehr/resources/queries/study/chemPivot.query.xml +++ b/onprc_ehr/resources/queries/study/chemPivot.query.xml @@ -19,7 +19,7 @@ - + Testing Performed By diff --git a/onprc_ehr/resources/queries/study/chemPivot.sql b/onprc_ehr/resources/queries/study/chemPivot.sql index 809c35117..cd3f3f8ce 100644 --- a/onprc_ehr/resources/queries/study/chemPivot.sql +++ b/onprc_ehr/resources/queries/study/chemPivot.sql @@ -13,7 +13,7 @@ FROM b.Id, b.date, b.method, - b.createdby, ---Added 5-10-2017 R.Blasa + b.performedby, ---Added 2-21-2020 R.Blasa b.testId, group_concat(b.result) as results FROM ( @@ -26,8 +26,7 @@ FROM --NOTE: removed to allow legacy runs to group into 1 row. since we already group on Id/Date/Test, this should be ok --coalesce(b.taskId, b.runId) as groupingId, b.runid.method as method, - b.createdby.DisplayName as createdby, ---Added 5-10-2017 R.Blasa - + b.performedby, ---Added 2-21-2020 R.Blasa b.remark, b.runId.remark as runRemark, b.resultoorindicator, @@ -40,8 +39,8 @@ FROM ) b - --Updated 6-3-2015 Blasa - GROUP BY b.runid,b.id, b.date, b.testId, b.method, b.createdby + ---Updated 2-21-2020 Blasa + GROUP BY b.runid,b.id, b.date, b.testId, b.method, b.performedby PIVOT results BY testId IN (select testid from ehr_lookups.chemistry_tests t WHERE t.includeInPanel = true order by sort_order)) pivot_ LEFT OUTER JOIN diff --git a/onprc_ehr/resources/queries/study/dualassigned.sql b/onprc_ehr/resources/queries/study/dualassigned.sql new file mode 100644 index 000000000..326d42499 --- /dev/null +++ b/onprc_ehr/resources/queries/study/dualassigned.sql @@ -0,0 +1,104 @@ +SELECT a.Id, +a.id.demographics.gender, +-- +a.project as Project1, +a2.project as Project2, +Case + when a.project.use_category != 'Research' then a.project + when a2.project.use_category != 'Research' then a2.project + else Null + end as project, + +Case + when a.project.use_category != 'Research' then a.project.account.alias + when a2.project.use_category != 'Research' then a2.project.account.alias + else Null + end as projectAccount, +Case + when a.project.use_category != 'Research' then a.project.displayname + when a2.project.use_category != 'Research' then a2.project.displayName + else Null + end as projectName, + + +Case + when a.project.use_category != 'Research' then a.project.use_category + when a2.project.use_category != 'Research' then a2.project.use_category + else Null + end as projectCategory, +--date should be the assignment date of the resource +Case + when a.project.use_category != 'Research' then a.date + when a2.project.use_category != 'Research' then a2.date + else Null + end as date, + +Case + when a.project.use_category != 'Research' then a.projectedRelease + when a2.project.use_category != 'Research' then a2.projectedRelease + else Null + end as projectedRelease, +Case + when a.project.use_category != 'Research' then a.enddate + when a2.project.use_category != 'Research' then a2.enddate + else Null + end as enddate, + +Case + when a.project.use_category != 'Research' then a.assignCondition + when a2.project.use_category != 'Research' then a2.assignCondition + else Null + end as assignCondition, + +Case + when a.project.use_category != 'Research' then a.projectedReleaseCondition + when a2.project.use_category != 'Research' then a2.projectedReleaseCondition + else Null + end as projectedReleaseCondition, + + + + +--this places the research project as the Dual assigned +Case + When a2.project.use_category = 'Research' then a2.project + when a.project.use_category = 'Research' then a.project + Else Null + ENd as DualAssignment, +--a2.project as DualAssignment, +Case + When a2.project.use_category = 'Research' then a2.project.displayName + when a.project.use_category = 'Research' then a.project.DisplayName + Else Null + ENd as DualName, + +--this places the research project as the Dual assigned +Case + When a2.project.use_category = 'Research' then a2.project.use_category + when a.project.use_category = 'Research' then a.project.use_category + Else Null + ENd as DualProjectCategory, +Case + When a2.project.use_category = 'Research' then a2.date + when a.project.use_category = 'Research' then a.date + Else Null + ENd as DualStartDate, + +Case + When a2.project.use_category = 'Research' then a2.projectedRelease + when a.project.use_category = 'Research' then a.projectedRelease + Else Null + ENd as DualProjectedRelease, + +Case + When a2.project.use_category = 'Research' then a2.enddate + when a.project.use_category = 'Research' then a.enddate + Else Null + ENd as DualEndDate + + + + + +FROM "/ONPRC/EHR".study.assignment a left outer join "/ONPRC/EHR".study.assignment a2 on a.id = a2.id +where ( a.project <> a2.project) and a.project.use_category != 'Research' diff --git a/onprc_ehr/resources/queries/study/hematologyPivot.query.xml b/onprc_ehr/resources/queries/study/hematologyPivot.query.xml index 4247f31cc..7713cb3c8 100644 --- a/onprc_ehr/resources/queries/study/hematologyPivot.query.xml +++ b/onprc_ehr/resources/queries/study/hematologyPivot.query.xml @@ -30,7 +30,7 @@ - + Testing Performed By diff --git a/onprc_ehr/resources/queries/study/hematologyPivot.sql b/onprc_ehr/resources/queries/study/hematologyPivot.sql index 70a4459f5..6c811d947 100644 --- a/onprc_ehr/resources/queries/study/hematologyPivot.sql +++ b/onprc_ehr/resources/queries/study/hematologyPivot.sql @@ -13,7 +13,7 @@ FROM b.id, b.date, b.method, - b.createdby, ---Added 5-10-2017 R.Blasa + b.performedby, ---Added 2-21-2020 R.Blasa b.testId, b.runId @hidden, group_concat(b.result) as results @@ -25,7 +25,7 @@ FROM b.date, b.testId, b.runid.method as method, - b.createdby.DisplayName as createdby, ---Added 5-10-2017 R.Blasa + b.performedby as performedby, ---Added 2-21-2020 R.Blasa coalesce(b.runId, b.objectid) as runId, CASE WHEN b.result IS NULL THEN b.qualresult @@ -35,7 +35,7 @@ FROM WHERE b.testId.includeInPanel = true and b.qcstate.publicdata = true ) b -GROUP BY b.id, b.date, b.runId, b.testId, b.method,b.createdby +GROUP BY b.id, b.date, b.runId, b.testId, b.method, b.performedby PIVOT results BY testId IN (select testid from ehr_lookups.hematology_tests t WHERE t.includeInPanel = true order by sort_order)) pvt @@ -47,7 +47,7 @@ LEFT OUTER JOIN group_concat(distinct servicerequested, chr(10)) as servicerequested, b.runId, b.method, - b.createdby, ---Added 5-10-2017 R.Blasa, + b.performedby, ---Added 2-21-2020 R.Blasa, group_concat(distinct b.remark, chr(10)) as remark, group_concat(distinct b.runRemark, chr(10)) as runRemark @@ -57,7 +57,7 @@ FROM ( b.id, b.date, b.runid.method as method, - b.createdby.DisplayName as createdby, ---Added 5-10-2017 R.Blasa + b.performedby as performedby, ---Added 5-10-2020 R.Blasa b.runid.servicerequested as servicerequested, coalesce(b.runId, b.objectid) as runId, b.remark, @@ -66,6 +66,6 @@ FROM ( WHERE b.testId.includeInPanel = true and b.qcstate.publicdata = true ) b -GROUP BY b.id, b.date, b.runId, b.method, b.createdby) grp +GROUP BY b.id, b.date, b.runId, b.method, performedby) grp -ON pvt.id = grp.id AND pvt.date = grp.date AND pvt.runID = grp.runId AND pvt.method = grp.method AND pvt.createdby = grp.createdby \ No newline at end of file +ON pvt.id = grp.id AND pvt.date = grp.date AND pvt.runID = grp.runId AND pvt.method = grp.method AND pvt.performedby = grp.performedby \ No newline at end of file diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index 2b340b6d2..2c89bbea0 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -13,6 +13,101 @@ var triggerHelper = new org.labkey.onprc_ehr.query.ONPRC_EHRTriggerHelper(LABKEY exports.init = function(EHR){ EHR.ETL = ETL; + EHR.Server.TriggerManager.registerHandler(EHR.Server.TriggerManager.Events.INIT, function (event, helper, EHR) { + + EHR.Server.TriggerManager.unregisterAllHandlersForQueryNameAndEvent('study', 'birth', EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC); + + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.ON_BECOME_PUBLIC, 'study', 'birth', function (scriptErrors, helper, row, oldRow) { + // Put custom ONPRC handler here + // skip normal birth records process when birth condition has a value of Fetus + console.log("onprc_ehr/birth.js entry") + if (row.Id && row.birth_condition == 'Fetus - Prenatal') + { + var obj = { + Id: row.Id, + birth: row.date, + date: row.date, + calculated_status: 'Fetus' + }; + + + helper.getJavaHelper().createDemographicsRecord(row.Id, obj); + } + + else + { + var isLiving = EHR.Server.Utils.isLiveBirth(row.birth_condition); + if (isLiving) + { + helper.registerLiveBirth(row.Id, row.date); + } + + if (!helper.isETL()) + { + //if a weight is provided, we insert into the weight table: + if (row.weight && row.wdate) + { + helper.getJavaHelper().insertWeight(row.Id, row.wdate, row.weight); + } + + //if room provided, we insert into housing. if this animal already has an active housing record, skip + + if (row.room && row.Id && row.date) + { + + helper.getJavaHelper().createHousingRecord(row.Id, row.date, (isLiving ? null : row.date), row.room, (row.cage || null),null); + } + + if (!helper.isGeneratedByServer()) + { + var obj = { + Id: row.Id, + gender: row.gender, + dam: row.dam, + sire: row.sire, + origin: row.origin, + birth: row.date, + date: row.date, + calculated_status: isLiving ? 'Alive' : 'Dead' + + }; + + //NOTE: the follow is designed to allow the table to either have physical columns for species/origin, or do display the demographics values. in the latter case, editing the form field will act to update the demographics record + if (row.species || row['Id/demographics/species']) + { + obj.species = row.species || row['Id/demographics/species']; + } + + if (row.geographic_origin || row['Id/demographics/geographic_origin']) + { + obj.geographic_origin = row.geographic_origin || row['Id/demographics/geographic_origin']; + } + + //find dam, if provided + if (row.dam && !obj.geographic_origin) + { + obj.geographic_origin = helper.getJavaHelper().getGeographicOrigin(row.dam); + } + + if (row.dam && !obj.species) + { + obj.species = helper.getJavaHelper().getSpecies(row.dam); + } + + if (!isLiving) + { + obj.death = row.date; + } + + //if not already present, we insert into demographics + helper.getJavaHelper().createDemographicsRecord(row.Id, obj); + } + } + } + }); + }); + + EHR.Server.TriggerManager.registerHandler(EHR.Server.TriggerManager.Events.INIT, function(event, helper, EHR){ EHR.Server.Utils.isLiveBirth = function(birthCondition){ EHR.Assert.assertNotEmpty('triggerHelper is null', triggerHelper); diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/ClinpathRunsClientStore.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/ClinpathRunsClientStore.js new file mode 100644 index 000000000..361d3b549 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/ClinpathRunsClientStore.js @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @param fieldConfigs + */ + +//Created: 3-12-2020 R.Blasa + +Ext4.define('ONPRC_EHR.data.ClinpathRunsClientStore', { + extend: 'EHR.data.DataEntryClientStore', + + constructor: function(){ + this.callParent(arguments); + + this.on('add', this.onAddRecord, this); + }, + + onAddRecord: function(store, records){ + Ext4.each(records, function(record){ + var modified = ['servicerequested']; + if (record.get('chargetype')){ + modified.push('chargetype'); + } + this.onRecordUpdate(record, modified); + }, this); + }, + + afterEdit: function(record, modifiedFieldNames){ + this.onRecordUpdate(record, modifiedFieldNames); + + this.callParent(arguments); + }, + + onRecordUpdate: function(record, modifiedFieldNames){ + if (record.get('servicerequested')){ + modifiedFieldNames = modifiedFieldNames || []; + + var storeId = LABKEY.ext4.Util.getLookupStoreId({ + lookup: { + schemaName: 'onprc_ehr', + queryName: 'labServiceRequest_Active', + keyColumn: 'servicename', + displayColumn: 'servicename' + } + }); + + var store = Ext4.StoreMgr.get(storeId); + if (!store){ + LDK.Utils.logToServer({ + message: 'Unable to find lookup store in ClinpathRunsClientStore' + }); + console.error('Unable to find lookup store in ClinpathRunsClientStore'); + + return; + } + + var lookupRecIdx = store.findExact('servicename', record.get('servicerequested')); + if (lookupRecIdx == -1){ + LDK.Utils.logToServer({ + message: 'Unable to find lookup record in ClinpathRunsClientStore' + }); + console.error('Unable to find lookup record in ClinpathRunsClientStore'); + + return; + } + + var lookupRec = store.getAt(lookupRecIdx); + var params = {}; + if (lookupRec.get('dataset')) + params.type = lookupRec.get('dataset'); + + //NOTE: if setting both service and chargetype simultaneously, do not override that selection + if (modifiedFieldNames.indexOf('servicerequested') > -1 && modifiedFieldNames.indexOf('chargetype') == -1 && lookupRec.get('chargetype')){ + //only update if using a standard value + if (!record.get('chargetype') || record.get('chargetype') == 'Clinpath' || record.get('chargetype') == 'SPF Surveillance Lab') + params.chargetype = lookupRec.get('chargetype'); + } + + if (modifiedFieldNames.indexOf('servicerequested') > -1 && lookupRec.get('tissue')){ + params.tissue = lookupRec.get('tissue'); + } + + if (!LABKEY.Utils.isEmptyObj(params)){ + record.beginEdit(); + record.set(params); + record.endEdit(true); + } + } + + //also cascade update children if Id/date changes + if (modifiedFieldNames && (modifiedFieldNames.indexOf('Id') > -1 || modifiedFieldNames.indexOf('project') > -1)){ + if (record.get('objectid')){ + if (!this.storeCollection){ + LDK.Utils.logError('this.storeCollection is null in ClinpathRunsClientStore'); + return; + } + + this.storeCollection.clientStores.each(function(cs){ + if (cs.storeId == this.storeId){ + return; + } + + var hasProject = cs.getFields().get('project') != null; + var hasChanges = false; + + if (cs.getFields().get('runid')){ + if (cs.getFields().get('Id') || cs.getFields().get('project')){ + cs.each(function(r){ + if (r.get('runid') === record.get('objectid')){ + var obj = {}; + if (hasProject && r.get('project') !== record.get('project')){ + obj.project = record.get('project'); + } + + if (r.get('Id') !== record.get('Id')){ + obj.Id = record.get('Id'); + } + + if (!Ext4.Object.isEmpty(obj)){ + r.beginEdit(); + r.set(obj); + r.endEdit(true); + hasChanges = true; + } + } + }, this); + } + } + + if (hasChanges){ + cs.fireEvent('datachanged', cs); + } + }, this); + } + } + } +}); diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/labworkPanel.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/labworkPanel.js index 3b8da502b..0f3875f2b 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/labworkPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/labworkPanel.js @@ -10,6 +10,29 @@ EHR.model.DataModelManager.registerMetadata('LabworkPanel', { }, byQuery: { 'study.clinpathRuns': { + servicerequested: { + allowBlank: false, + columnConfig: { + width: 250 + }, + lookup: { + xtype: 'labkey-combo', + schemaName: 'onprc_ehr', + queryName: 'labServiceRequest_Active', + keyColumn: 'servicename', + columns: '*', + sort: 'chargetype,servicename,outsidelab' + }, + editorConfig: { + anyMatch: true, + listConfig: { + innerTpl: '{[(values.chargetype ? "" + values.chargetype + ": " : "") + values.servicename + (values.outsidelab ? "*" : "")]}', + getInnerTpl: function () { + return this.innerTpl; + } + } + } + }, performedby: { defaultValue: LABKEY.Security.currentUser.displayName , diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 85244b66f..53649494d 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -20,6 +20,8 @@ import org.labkey.api.ehr.EHRService; import org.labkey.api.ehr.buttons.ChangeQCStateButton; import org.labkey.api.ehr.buttons.CreateTaskFromIdsButton; +import org.labkey.api.ehr.buttons.CreateTaskFromRecordsButton; +import org.labkey.api.ehr.buttons.DiscardTaskButton; import org.labkey.api.ehr.buttons.EHRShowEditUIButton; import org.labkey.api.ehr.buttons.MarkCompletedButton; import org.labkey.api.ehr.buttons.ReassignRequestButton; @@ -31,30 +33,33 @@ import org.labkey.api.ldk.ExtendedSimpleModule; import org.labkey.api.ldk.buttons.ShowEditUIButton; import org.labkey.api.ldk.notification.NotificationService; +import org.labkey.api.module.AdminLinkManager; import org.labkey.api.module.Module; import org.labkey.api.module.ModuleContext; import org.labkey.api.query.DefaultSchema; import org.labkey.api.query.DetailsURL; import org.labkey.api.query.QuerySchema; import org.labkey.api.resource.Resource; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.security.roles.RoleManager; import org.labkey.api.settings.AppProps; import org.labkey.api.util.URLHelper; import org.labkey.api.util.UnexpectedException; +import org.labkey.api.view.ActionURL; +import org.labkey.api.view.NavTree; import org.labkey.api.view.template.ClientDependency; import org.labkey.onprc_ehr.buttons.AnimalGroupCompletedButton; import org.labkey.onprc_ehr.buttons.AssignmentCompletedButton; import org.labkey.onprc_ehr.buttons.AssignmentReleaseConditionButton; import org.labkey.onprc_ehr.buttons.BulkEditRequestsButton; import org.labkey.onprc_ehr.buttons.ChangeProjectedReleaseDateButton; +import org.labkey.onprc_ehr.buttons.CreateNecropsyRequestButton; import org.labkey.onprc_ehr.buttons.CreateProjectButton; -import org.labkey.onprc_ehr.buttons.DiscardTaskButton; import org.labkey.onprc_ehr.buttons.HousingTransferButton; import org.labkey.onprc_ehr.buttons.ManageFlagsButton; import org.labkey.onprc_ehr.buttons.ProtocolEditButton; import org.labkey.onprc_ehr.buttons.VetReviewButton; import org.labkey.onprc_ehr.buttons.VetReviewRecordButton; -import org.labkey.onprc_ehr.buttons.CreateTaskFromRecordButtons; import org.labkey.onprc_ehr.dataentry.*; import org.labkey.onprc_ehr.demographics.ActiveAnimalGroupsDemographicsProvider; import org.labkey.onprc_ehr.demographics.ActiveCasesDemographicsProvider; @@ -63,11 +68,11 @@ import org.labkey.onprc_ehr.demographics.CagematesDemographicsProvider; import org.labkey.onprc_ehr.demographics.FosterChildDemographicsProvider; import org.labkey.onprc_ehr.demographics.HousingDemographicsProvider; +import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.demographics.ParentsDemographicsProvider; import org.labkey.onprc_ehr.demographics.PregnancyConfirmDemographicsProvider; import org.labkey.onprc_ehr.demographics.SourceDemographicsProvider; import org.labkey.onprc_ehr.demographics.TBDemographicsProvider; -import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalGroupsEndDataSource; import org.labkey.onprc_ehr.history.DefaultAnimalRecordFlagDataSource; @@ -381,6 +386,7 @@ public String toString() EHRService.get().registerActionOverride("cageDetails", this, "views/cageDetails.html"); EHRService.get().registerActionOverride("animalSearch", this, "views/animalSearch.html"); EHRService.get().registerActionOverride("animalHistory", this, "views/animalHistory.html"); + EHRService.get().registerActionOverride("serviceRequests", this, "views/serviceRequests.html"); //Added: 10-2-2017 R.Blasa displays onperc version of enterData.view EHRService.get().registerActionOverride("enterData", this, "views/enterData.html"); @@ -403,6 +409,7 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(SingleSurgeryFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyFormType.class, this)); + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NecropsyRequestForm.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(BiopsyFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PathologyTissuesFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ClinicalReportFormType.class, this)); @@ -421,7 +428,7 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ParentageFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(GeneticAncestryFormType.class, this)); - EHRService.get().registerFormType(new DefaultDataEntryFormFactory(BloodDrawFormType.class, this)); + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ONPRCBloodDrawFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(AuxProcedureFormType.class, this)); //Modified: 12-13-2016 R.Blasa @@ -521,20 +528,19 @@ public String toString() editBtn.setCopyFilters(false); EHRService.get().registerMoreActionsButton(editBtn, "study", "flags"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Blood Draw For Selected", "Blood Draws", BloodDrawFormType.NAME, new String[]{"Blood Draws"}), "study", "demographics"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Blood Draw For Selected", "Blood Draws", ONPRCBloodDrawFormType.NAME, new String[]{"Blood Draws"}), "study", "demographics"); //EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Weight For Selected", "Weight", "weight", new String[]{"Weight"}), "study", "demographics"); //EHRService.get().registerMoreActionsButton(new CreateTaskFromIdsButton(this, "Schedule Weight For Selected", "Weight", "weight", new String[]{"Weight"}), "study", "weight"); EHRService.get().registerTbarButton(new HousingTransferButton(this), "onprc_ehr", "housing_transfer_requests"); - //Modified: 1-18-2019 R.Blasa - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Blood Draws", BloodDrawFormType.NAME), "study", "blood"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Treatments/Medications", TreatmentsFormType.NAME), "study", "drug"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Labwork", LabworkFormType.NAME), "study", "clinpathRuns"); - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Blood Draws", ONPRCBloodDrawFormType.NAME), "study", "blood"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Treatments/Medications", TreatmentsFormType.NAME), "study", "drug"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Labwork", LabworkFormType.NAME), "study", "clinpathRuns"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Surgeries", SurgeryFormType.NAME), "study", "surgery"); - //Added: 1-18-2019 R.Blasa - EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordButtons(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); + //Added: 7-29-2017 R.Blasa + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Procedures", AuxProcedureFormType.NAME), "study", "encounters"); EHRService.get().registerMoreActionsButton(new ChangeQCStateButton(this), "study", "blood"); @@ -575,16 +581,32 @@ public String toString() EHRService.get().registerHistoryDataSource(new org.labkey.api.ehr.history.DefaultAnimalRecordFlagDataSource(this)); EHRService.get().registerHistoryDataSource(new ONPRCClinicalRemarksDataSource(this)); + EHRService.get().registerMoreActionsButton(new CreateNecropsyRequestButton(this), "study", "encounters"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "encounters"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "tissue_samples"); + EHRService.get().registerMoreActionsButton(new CreateTaskFromRecordsButton(this, "Create Task From Selected", "Necropsy", NecropsyFormType.NAME), "study", "organ_weights"); + EHRService.get().registerOptionalClinicalHistoryResources(this); EHRService.get().registerLabworkType(new ONPRCUrinalysisLabworkType(this)); EHRService.get().registerLabworkType(new ONPRCiStatLabworkType(this)); - //R.Blasa 11-28-2016 EHRService.get().registerHistoryDataSource(new DefaultNHPTrainingDataSource(this)); + //R.Blasa 11-20-2019 EHRService.get().registerHistoryDataSource(new DefaultSustainedReleaseDatasource(this)); + + + + AdminLinkManager.getInstance().addListener((adminNavTree, container, user) -> + { + if (container.hasPermission(user, AdminPermission.class) && container.getActiveModules().contains(ONPRC_EHRModule.this)) + { + adminNavTree.addChild(new NavTree("EHR Admin Page", new ActionURL("onprc_ehr", "ehrAdmin", container))); + } + }); + } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index 4c59a8b65..da5a1a85f 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -45,9 +45,13 @@ import org.labkey.api.ehr.notification.AbstractEHRNotification; import org.labkey.onprc_ehr.ONPRC_EHRManager; +import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.ContainerFilterable; + import java.sql.ResultSet; import java.sql.SQLException; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -926,6 +930,11 @@ protected void incompleteBirthRecords(final Container c, User u, final StringBui keys.add(FieldKey.fromString("Id/demographics/calculated_status")); keys.add(FieldKey.fromString("Id/demographics/geographic_origin")); +// Modified: 2-20-2020 R. Blasa + keys.add(FieldKey.fromString("date")); + keys.add(FieldKey.fromString("remark")); + + final Map cols = QueryService.get().getColumns(ti, keys); TableSelector ts = new TableSelector(ti, cols.values(), filter, new Sort(getStudy(c).getSubjectColumnName())); long count = ts.getRowCount(); @@ -933,7 +942,7 @@ protected void incompleteBirthRecords(final Container c, User u, final StringBui { msg.append("WARNING: There are " + count + " finalized birth records within the past 30 days lacking information:

    \n"); msg.append(""); - msg.append(""); + msg.append(""); ts.forEach(new Selector.ForEachBlock() { @Override @@ -947,6 +956,11 @@ public void exec(ResultSet object) throws SQLException msg.append(""); msg.append(""); msg.append(""); + + //Added: 2-20-2020 R.Blasa + msg.append(""); + msg.append(""); + msg.append(""); msg.append(""); msg.append(""); @@ -1037,6 +1051,270 @@ protected void bsuNotesAlert(final Container c, User u, final StringBuilder msg) } /** +<<<<<<< .mine + * Kollil, 10/24/2019 : PMIC scheduler alert notifications Daily & Weekly + */ + protected void pmicSchedulerAlert(final Container c, User u, final StringBuilder msg) + { + //PMIC container: 783D2EA5-C6AC-1036-A33C-BD25D0574070 + if (QueryService.get().getUserSchema(u, c, "extscheduler") == null) { + msg.append("Warning: The extscheduler schema has not been enabled in this folder, so the alert cannot run!


    "); + return; + } + //Daily events query + TableInfo ti = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler"); + ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); + TableSelector ts = new TableSelector(ti, null, null); + long count = ts.getRowCount(); + + //Weekly events query + TableInfo ti1 = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler_Weekly"); + ((ContainerFilterable) ti1).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); + TableSelector ts1 = new TableSelector(ti1, null, null); + long count1 = ts1.getRowCount(); + + if (count > 0) {//Daily events count + msg.append("There are " + count + " PMIC events scheduled for today:"); + msg.append("

    Click here to view them

    \n"); + msg.append("
    "); + } + if (count1 > 0) {//Weekly events count + msg.append("There are " + count1 + " PMIC events scheduled this week:"); + msg.append("

    Click here to view them

    \n"); + msg.append("
    "); + } + //Display the daily report in the email + if (count > 0) { + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("resourceid")); + columns.add(FieldKey.fromString("startdate")); + columns.add(FieldKey.fromString("enddate")); + columns.add(FieldKey.fromString("name")); + columns.add(FieldKey.fromString("alias")); + columns.add(FieldKey.fromString("quantity")); + columns.add(FieldKey.fromString("comments")); + columns.add(FieldKey.fromString("color")); + columns.add(FieldKey.fromString("room")); + columns.add(FieldKey.fromString("bldg")); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts2 = new TableSelector(ti, colMap.values(), null, null); + count = ts2.getRowCount(); + + if (count == 0) { + msg.append("There are no scheduled PMIC events"); + } + else { + msg.append("
    Daily PMIC events:

    \n"); + msg.append("
    IdStatusGenderSpeciesGeographic Origin
    IdStatusBirth DateRemarksGenderSpeciesGeographic Origin
    " + rs.getString("Id") + "" + (rs.getString(FieldKey.fromString("Id/demographics/calculated_status")) == null ? "Unknown" : rs.getString(FieldKey.fromString("Id/demographics/calculated_status"))) + "" + (rs.getString("date") == null ? "Unknown" : rs.getDate("date")) + "" + (rs.getString("remark") == null ? " " : rs.getString("remark")) + "" + (rs.getString(FieldKey.fromString("Id/demographics/gender/meaning")) == null ? "MISSING" : rs.getString(FieldKey.fromString("Id/demographics/gender/meaning"))) + "" + (rs.getString(FieldKey.fromString("Id/demographics/species")) == null ? "MISSING" : rs.getString(FieldKey.fromString("Id/demographics/species"))) + "" + (rs.getString(FieldKey.fromString("Id/demographics/geographic_origin")) == null ? "MISSING" : rs.getString(FieldKey.fromString("Id/demographics/geographic_origin"))) + "
    "); + msg.append(""); + msg.append(""); + + ts2.forEach(new Selector.ForEachBlock() { + @Override + public void exec(ResultSet object) throws SQLException { + Results rs = new ResultsImpl(object, colMap); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + } + }); + msg.append("
    Resource Id Start Date End Date Name Alias Quantity Comments Color Room Bldg
    " + rs.getString("resourceid") + "" + rs.getString("startdate") + "" + rs.getString("enddate") + "" + rs.getString("name") + "" + rs.getString("alias") + "" + rs.getString("quantity") + "" + rs.getString("comments") + "" + rs.getString("color") + "" + rs.getString("room") + "" + rs.getString("bldg") + "
    "); + } + //Display the weekly report in the email + if (count1 > 0) { + Set columns1 = new HashSet<>(); + columns1.add(FieldKey.fromString("resourceid")); + columns1.add(FieldKey.fromString("startdate")); + columns1.add(FieldKey.fromString("enddate")); + columns1.add(FieldKey.fromString("name")); + columns1.add(FieldKey.fromString("alias")); + columns1.add(FieldKey.fromString("quantity")); + columns1.add(FieldKey.fromString("comments")); + columns1.add(FieldKey.fromString("color")); + columns1.add(FieldKey.fromString("room")); + columns1.add(FieldKey.fromString("bldg")); + + final Map colMap1 = QueryService.get().getColumns(ti1, columns1); + TableSelector ts3 = new TableSelector(ti1, colMap1.values(), null, null); + count1 = ts3.getRowCount(); + + if (count1 == 0) { + msg.append("There are no scheduled PMIC events"); + } + else { + msg.append("

    Weekly PMIC events:

    \n"); + msg.append(""); + msg.append(""); + msg.append(""); + + ts3.forEach(new Selector.ForEachBlock() { + @Override + public void exec(ResultSet object) throws SQLException { + Results rs1 = new ResultsImpl(object, colMap1); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + } + }); + msg.append("
    Resource Id Start Date End Date Name Alias Quantity Comments Color Room Bldg
    " + rs1.getString("resourceid") + "" + rs1.getString("startdate") + "" + rs1.getString("enddate") + "" + rs1.getString("name") + "" + rs1.getString("alias") + "" + rs1.getString("quantity") + "" + rs1.getString("comments") + "" + rs1.getString("color") + "" + rs1.getString("room") + "" + rs1.getString("bldg") + "
    "); + } + } + } + } + + /** +||||||| .r64573 +======= + * Kollil, 10/24/2019 : PMIC scheduler alert notifications Daily & Weekly + */ +// protected void pmicSchedulerAlert(final Container c, User u, final StringBuilder msg) +// { +// //PMIC container: 783D2EA5-C6AC-1036-A33C-BD25D0574070 +// if (QueryService.get().getUserSchema(u, c, "extscheduler") == null) { +// msg.append("Warning: The extscheduler schema has not been enabled in this folder, so the alert cannot run!


    "); +// return; +// } +// //Daily events query +// TableInfo ti = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler"); +// ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); +// TableSelector ts = new TableSelector(ti, null, null); +// long count = ts.getRowCount(); +// +// //Weekly events query +// TableInfo ti1 = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler_Weekly"); +// ((ContainerFilterable) ti1).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); +// TableSelector ts1 = new TableSelector(ti1, null, null); +// long count1 = ts1.getRowCount(); +// +// if (count > 0) {//Daily events count +// msg.append("There are " + count + " PMIC events scheduled for today:"); +// msg.append("

    Click here to view them

    \n"); +// msg.append("
    "); +// } +// if (count1 > 0) {//Weekly events count +// msg.append("There are " + count1 + " PMIC events scheduled this week:"); +// msg.append("

    Click here to view them

    \n"); +// msg.append("
    "); +// } +// //Display the daily report in the email +// if (count > 0) { +// Set columns = new HashSet<>(); +// columns.add(FieldKey.fromString("resourceid")); +// columns.add(FieldKey.fromString("startdate")); +// columns.add(FieldKey.fromString("enddate")); +// columns.add(FieldKey.fromString("name")); +// columns.add(FieldKey.fromString("alias")); +// columns.add(FieldKey.fromString("quantity")); +// columns.add(FieldKey.fromString("comments")); +// columns.add(FieldKey.fromString("color")); +// columns.add(FieldKey.fromString("room")); +// columns.add(FieldKey.fromString("bldg")); +// +// final Map colMap = QueryService.get().getColumns(ti, columns); +// TableSelector ts2 = new TableSelector(ti, colMap.values(), null, null); +// count = ts2.getRowCount(); +// +// if (count == 0) { +// msg.append("There are no scheduled PMIC events"); +// } +// else { +// msg.append("
    Daily PMIC events:

    \n"); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// +// ts2.forEach(new Selector.ForEachBlock() { +// @Override +// public void exec(ResultSet object) throws SQLException { +// Results rs = new ResultsImpl(object, colMap); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// } +// }); +// msg.append("
    Resource Id Start Date End Date Name Alias Quantity Comments Color Room Bldg
    " + rs.getString("resourceid") + "" + rs.getString("startdate") + "" + rs.getString("enddate") + "" + rs.getString("name") + "" + rs.getString("alias") + "" + rs.getString("quantity") + "" + rs.getString("comments") + "" + rs.getString("color") + "" + rs.getString("room") + "" + rs.getString("bldg") + "
    "); +// } +// //Display the weekly report in the email +// if (count1 > 0) { +// Set columns1 = new HashSet<>(); +// columns1.add(FieldKey.fromString("resourceid")); +// columns1.add(FieldKey.fromString("startdate")); +// columns1.add(FieldKey.fromString("enddate")); +// columns1.add(FieldKey.fromString("name")); +// columns1.add(FieldKey.fromString("alias")); +// columns1.add(FieldKey.fromString("quantity")); +// columns1.add(FieldKey.fromString("comments")); +// columns1.add(FieldKey.fromString("color")); +// columns1.add(FieldKey.fromString("room")); +// columns1.add(FieldKey.fromString("bldg")); +// +// final Map colMap1 = QueryService.get().getColumns(ti1, columns1); +// TableSelector ts3 = new TableSelector(ti1, colMap1.values(), null, null); +// count1 = ts3.getRowCount(); +// +// if (count1 == 0) { +// msg.append("There are no scheduled PMIC events"); +// } +// else { +// msg.append("

    Weekly PMIC events:

    \n"); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// +// ts3.forEach(new Selector.ForEachBlock() { +// @Override +// public void exec(ResultSet object) throws SQLException { +// Results rs1 = new ResultsImpl(object, colMap1); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// msg.append(""); +// } +// }); +// msg.append("
    Resource Id Start Date End Date Name Alias Quantity Comments Color Room Bldg
    " + rs1.getString("resourceid") + "" + rs1.getString("startdate") + "" + rs1.getString("enddate") + "" + rs1.getString("name") + "" + rs1.getString("alias") + "" + rs1.getString("quantity") + "" + rs1.getString("comments") + "" + rs1.getString("color") + "" + rs1.getString("room") + "" + rs1.getString("bldg") + "
    "); +// } +// } +// } +// } + + /** +>>>>>>> .r65353 * we find protocols over the animal limit */ protected void protocolsOverLimit(final Container c, User u, final StringBuilder msg) @@ -1855,10 +2133,23 @@ protected void infantsNotWithMother(final Container c, User u, final StringBuild { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Id/age/ageInDays"), 180, CompareType.LTE); //Added by Kolli1, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates - //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG+;RABBIT", CompareType.CONTAINS_NONE_OF); + //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG;RABBIT", CompareType.CONTAINS_NONE_OF); filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG", CompareType.NEQ); filter.addCondition(FieldKey.fromString("Id/demographics/calculated_status"), "Alive", CompareType.EQUAL); - filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 191", CompareType.NEQ_OR_NULL); + // Changed by Kolli on 3/6/2020 + /*Rm 191 used to be a nursery, but below are the current rooms where infants are likely to be housed without dams. Can you exclude these rooms, rather than ASB RM 191? + ASB RM 213 + ASB RM 236 + ASB RM 240 + ASB RM 185 + COL RM 4 + */ + //filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 191", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 213", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 236", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 240", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 185", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "COL RM 4", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("withMother"), 0, CompareType.EQUAL); TableInfo ti = getStudySchema(c, u).getTable("infantsSeparateFromMother"); @@ -1873,7 +2164,7 @@ protected void infantsNotWithMother(final Container c, User u, final StringBuild long count = ts.getRowCount(); if (count > 0) { - msg.append("NOTE: There are " + count + " animals under 180 days old not housed with their dam or foster dam, excluding animals in ASB RM 191

    "); + msg.append("NOTE: There are " + count + " animals under 180 days old not housed with their dam or foster dam, excluding animals in ASB RM 213, ASB RM 236, ASB RM 240, ASB RM 185 & COL RM 4

    "); ts.forEach(new Selector.ForEachBlock() { @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java index 3b99c0a67..bd6c974b3 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java @@ -122,6 +122,7 @@ public class ONPRC_EHRTriggerHelper private Map _cachedDividerRecords = new HashMap<>(); private static final String NONRESTRICTED = "Nonrestricted"; + private static final String TERMINAL = "Terminal"; private static final String EXPERIMENTAL_EUTHANASIA = "EUTHANASIA, EXPERIMENTAL"; private static final String NON_EXPERIMENTAL_EUTHANASIA = "EUTHANASIA, NONEXPERIMENTAL"; private static final String SPONTANEOUS_DEATH = "Spontaneous Death"; @@ -1402,7 +1403,10 @@ else if (flagList.size() == 0) row.put("enddate", enddate); row.put("project", project); row.put("assignCondition", getConditionCodeForMeaning(NONRESTRICTED)); - row.put("projectedReleaseCondition", getConditionCodeForMeaning(NONRESTRICTED)); + +// Modified: 4-13-2020 R.Blasa + row.put("projectedReleaseCondition", getConditionCodeForMeaning(TERMINAL)); + if (enddate != null) { row.put("releaseCondition", getConditionCodeForMeaning(NONRESTRICTED)); From 87d562e1d02fa8b147e245cc6f8a94f4342d8bff Mon Sep 17 00:00:00 2001 From: Binal Date: Wed, 7 Oct 2020 22:09:43 -0700 Subject: [PATCH 13/49] Merge from onprc19.1 r.65410 --- .../onprc_billing/LeaseFeeRates_Final.sql | 18 ++- .../LeaseFeeReleaseAdjustment.sql | 15 ++- .../onprc_billing/leaseFeeRates_2020.sql | 119 ++++++++++-------- .../onprc_billing/miscChargesWithRates.sql | 6 + .../onprc_billing/ONPRC_BillingModule.java | 13 +- 5 files changed, 105 insertions(+), 66 deletions(-) diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql index 159f2d300..33d04b569 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql @@ -1,6 +1,7 @@ --2020/02/12 build -SELECT r.Id, +SELECT +r.Id, r.date as BillingDate, r.enddate as ReleaseDate, r.CenterProject, @@ -57,22 +58,29 @@ r.canRaiseFA, r.BirthAssignment, r.BirthType, case + + When a.creditto is not null then 'Adjustment' When d.creditResource is not Null then d.creditResource Else 'p51' End as CreditTo, Case -When d.creditResource is not Null then d.creditTo + + when a.creditto is not null then a.creditto + when d.creditResource is not Null then d.creditTo else ca.account End as CreditAccount, case WHen r.releaseType = 'No Charge' then 0 + WHen r.releaseType = 'IACUC Excluded / No Charge' then 0 when r.researchOwned = 'Yes' then 0 - when r.DayLeaseLength > 0 and r.daylease = 'yes' then (r.dayleaseLength * r.CalculatedRate) - when r.revisedrate is not null and r.revisedrate > r.CalculatedRate then (r.revisedRate - r.CalculatedRate) - when r.revisedrate is not null and r.revisedrate < r.CalculatedRate then (r.CalculatedRate - r.RevisedRate) + when r.DayLeaseLength> 0 then (r.dayleaseLength * r.CalculatedRate) + --when r.revisedRate Is Not null then 2020 + when r.assignmentType = 'automatic_adjustment' and r.revisedrate > r.CalculatedRate then (r.revisedRate - r.CalculatedRate) + when r.assignmentType = 'automatic_adjustment' then ((r.CalculatedRate - r.RevisedRate) * -1) Else (1 * r.CalculatedRate) End as TotalCost, +r.calculatedRate, r.revisedRate diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql index a55bc8e42..3b9287b01 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql @@ -4,13 +4,14 @@ PARAMETERS (StartDate TIMESTAMP, EndDate TIMESTAMP) SELECT a.id, case - When a.enddate < a.dateFinalized then a.dateFinalized + When a.enddate <= a.dateFinalized then a.dateFinalized Else a.enddate End as date, --a.date, a.project, a.project.project as projectID, a.project.account as alias, +(Select h.account from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.projectAccountHistory h where h.project = a.project and (a.date => h.startDate and a.date =< h.enddate)) as AliasAtTime, a.project.account.farate as faRate, a.project.account.aliastype.removesubsidy as removeSubsidy, a.project.account.aliastype.canRaiseFA as CanRaiseFA, @@ -33,7 +34,11 @@ CASE else 1 end as quantity, lf2.chargeId as leaseCharge1, +lf2.chargeID.activeRate.Subsidy as Subsidy, +(Select r3.unitcost from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRates r3 where r3.chargeID = lf2.chargeID and r3.StartDate <= a.date and r3.endDate >= a.date) as Lf1Rate, +(Select r2.unitcost from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRates r2 where r2.chargeID = lf.chargeID and r2.StartDate <= a.date and r2.endDate >= a.date) as Lf2Rate, lf.chargeId as leaseCharge2, +a.project.account as CreditTo, a.objectid as sourceRecord, 'Adjustment - Automatic' as chargeCategory, 'Y' as isAdjustment, @@ -47,8 +52,8 @@ a.enddatefinalized FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf - ON (lf.assignCondition = a.assignCondition - AND lf.releaseCondition = a.releaseCondition + ON (lf.assignCondition = a.assignCondition.code + AND lf.releaseCondition = a.releaseCondition.code AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf.minAge OR lf.minAge IS NULL) AND (a.ageAtTime.AgeAtTimeYearsRounded < lf.maxAge OR lf.maxAge IS NULL) and (a.date >=lf.startDate @@ -56,8 +61,8 @@ LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer' ) LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf2 - ON (lf2.assignCondition = a.assignCondition - AND lf2.releaseCondition = a.projectedReleaseCondition + ON (lf2.assignCondition = a.assignCondition.code + AND lf2.releaseCondition = a.projectedReleaseCondition.code AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf2.minAge OR lf2.minAge IS NULL) AND (a.ageAtTime.AgeAtTimeYearsRounded < lf2.maxAge OR lf2.maxAge IS NULL) and (a.date >=lf2.startDate diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql index b789728c6..9a7bb5d27 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql @@ -1,51 +1,49 @@ --Corrested Issue with Adjustments and loading into Test --20200111 - changed source from rate data to a passthru with a lookup of rate name and unit cost -SELECT d.Id, +SELECT r.Id, r.leasetype, - d.ResearchOwned, - d.project, --integer - d.project.name as CenterProject, + r.ResearchOwned, + r.projectID, --integer + r.CenterProject, r.AliasAtTime, - d.AgeAtAssignment, - d.ageinyears, - d.AgeGroup, - d.BirthAssignment, - d.BirthType, - d.AssignmentType, - d.DayLease, - d.DayLeaseLength, --integer - d.MultipleAssignments, - d.CreditResource as dualassignment, - null as creditto, - d.date, - d.projectedRelease, - d.enddate, - d.datefinalized, - d.assignCondition, --integer - d.projectedReleaseCondition, --integer - d.releaseCondition, --integer - d.releaseType, - d.remark, - d.alias, - d.farate, - d.removesubsidy, - d.canRaiseFA, + r.AgeAtTime as AgeAtAssignment, + r.ageinyears, + r.AgeGroup, + r.BirthAssignment, + r.BirthType, + r.AssignmentType, + r.DayLease, + r.DayLeaseLength, --integer + r.MultipleAssignments, + r.CreditResource as dualassignment, + r.creditto, + r.assignmentdate, + r.projectedRelease, + r.releasedate, + r.datefinalized, + r.code as assignCondition, --integer + r.ProjectedReleaseCode as projectedReleaseCondition, --integer + r.releaseCondition, --integer + r.releaseType, + r.remark, + r.Currentalias, + r.farate, + r.removesubsidy, + r.canRaiseFA, r.ChargeID, --integer - i.Name as Item, - i.DepartmentCode as ServiceCenter, + r.ChargeItem as Item, + r.ServiceCenter, r.exemptionRate, r.Multiplier, r.subsidy, - RateCalc(r.AliasAtTime,r.chargeID,d.project,d.Date,.4) as CalculatedRate, + RateCalc(r.AliasAtTime,r.chargeID,r.projectID,r.assignmentDate,r.subsidy) as CalculatedRate, null as revisedRate, r.revisedChargeID, r.revisedSubsidy -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateChargeItem r join - Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project - join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project - join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeableItems i on i.rowID = r.chargeID +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateChargeItem r + union @@ -55,7 +53,7 @@ select a.researchowned, a.projectID, --intege a.project.name as CenterProject, - a.alias, + a.aliasAtTime, a.ageattime, 1 as ageinYears, --need to run function to return years '' as agegroup, @@ -63,11 +61,11 @@ select '' as BirthType, 'automatic_adjustment' as AssignmentTypeNA, '' as DayLease, - '' as DayLeaseLength, --integer + 1 as DayLeaseLength, --integer '' as MultipleAssignments, null as dualassignment, - null as creditto, - a.date, + a.creditto, + a.enddate as BillingDate, a.enddate as projectedrelease, a.enddate, a.datefinalized, @@ -85,9 +83,25 @@ select ii.DepartmentCode as ServiceCenter, null as exemptionRate, null as Multiplier, - null as subsidy, - RateCalc(a.alias,a.leasecharge1,a.projectID, a.date,a.farate) as CalculatedRate, - RateCalc(a.alias,a.leasecharge2,a.projectID, a.date,a.farate) as RevisedRate, + ii.activeRate.subsidy, + case + when a.dateFinalized < '5/1/2015' then 0 + when a.projectID = 1106 then 0 + When (a.removesubsidy = 'false' and a.canRaiseFa = 'false') then a.lf2rate + When (a.removesubsidy = 'true' or a.CanRaiseFa = 'true') then RateCalc(a.aliasAtTime,a.leasecharge1,a.projectID,a.assignmentStart,ii.activeRate.subsidy) + When (a.removesubsidy = 'false' or a.CanRaiseFa = 'true') then RateCalc(a.aliasAtTime,a.leasecharge1,a.projectID,a.assignmentStart,ii.activeRate.subsidy) + --Else RateCalc(a.aliasatTime,a.leasecharge2,a.projectID,a.enddate,ii.activeRate.subsidy) + else a.lf2rate + End as CalculatedRate, + + case + when a.dateFinalized < '5/1/2015' then 0 + when a.projectID = 1106 then 0 + When (a.removesubsidy = 'false' or a.canRaiseFa = 'false') then a.lf2Rate + + + Else RateCalc(a.aliasatTime,a.leasecharge2,a.projectID,a.enddate,a.subsidy) + End as RevisedRate, a.leaseCharge2, null as RevisedSubsidy @@ -131,16 +145,19 @@ Select r.comment as remark, null as alias2, null as farate, - null as removesubsidy, - null as canRaiseFA, + r.removesubsidy, + r.canRaiseFA, r.chargeID, --integer - r.chargeID.Name as Item, - r.serviceCenter as ServiceCenter, - null as exemptionRate, - Null as Multiplier, - null as Subsidy, - r.rateCalc, + + r.chargeID.Name as Item, + r.serviceCenter as ServiceCenter, + ' ' as IsExemption, + --Cast(r.isExemption as Float) as IsExemption, + r.PM_Multiplier, + r.chargeID.activeRate.Subsidy as Subsidy, + --' ' as Ratecalc, + RateCalc(r.account,r.charge_ID,r.projectID,r.Date,r.subsidy) as CalculatedRate, null as RevisedRate, null as rate2, null as RevisedSubsidy @@ -149,4 +166,4 @@ Select FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.miscChargesWithRates r WHERE cast(r.billingDate as date) >= CAST(StartDate as date) AND cast(r.billingDate as date) <= CAST(EndDate as date) -AND r.category IN ('Lease Fees', 'Lease Setup Fee', 'Lease Setup Fees') +AND r.category IN ('Lease Fees') \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql index ffe18c7fd..51bcc8189 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql @@ -7,6 +7,9 @@ SELECT COALESCE(p.debitedaccount, aliasAtTime.account) as account, p.chargetype, p.chargeId, + p.chargeId.rowid as Charge_ID, + cr.chargeID.activeRate.subsidy as subsidy, + p.project.project as ProjectID, COALESCE(p.chargetype.servicecenter, p.chargeId.departmentCode) as serviceCenter, coalesce(p.chargeId.name, p.item) as item, p.unitCost as MCEnteredUnitCost, @@ -56,6 +59,9 @@ SELECT p.created, p.createdby, p.taskId, + alias.aliasType.removeSubsidy as removeSubsidy, + pm.multiplier as PM_Multiplier, + alias.aliasType.canRaiseFA as canRaiseFa, coalesce(p.creditedaccount, cu.account, ce.account) as creditAccount, CASE WHEN (cu.account IS NOT NULL) THEN 'Charge Unit' ELSE 'Chargeable Item' END as creditAccountType, diff --git a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java index a5557ca1f..da247a92e 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java +++ b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java @@ -12,6 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + Cleanupo of file 4/11/2020 */ package org.labkey.onprc_billing; @@ -38,13 +39,11 @@ import org.labkey.api.security.roles.RoleManager; import org.labkey.api.view.ViewContext; import org.labkey.api.view.WebPartFactory; -import org.labkey.api.writer.ContainerUser; import org.labkey.onprc_billing.button.ChangeBillDateButton; import org.labkey.onprc_billing.button.ChargeEditButton; import org.labkey.onprc_billing.button.ProjectEditButton; import org.labkey.onprc_billing.dataentry.ChargesAdvancedFormType; import org.labkey.onprc_billing.dataentry.ChargesFormType; -//import org.labkey.onprc_billing.dataentry.ChargesVirologyCoreFormType; import org.labkey.onprc_billing.dataentry.ChargesVirologyCoreFormType; import org.labkey.onprc_billing.dataentry.ReversalFormType; import org.labkey.onprc_billing.notification.BillingValidationNotification; @@ -76,11 +75,11 @@ public String getName() { return NAME; } -//This was updated to match all sets + @Override public @Nullable Double getSchemaVersion() { - return 19.411; + return 20.411; } @Override @@ -126,6 +125,10 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext) //Added: 5/6/2018 Kollil EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ChargesVirologyCoreFormType.class, this)); + //Added: 1/6/2020 Kollil + /* EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ChargesARTCoreFormType.class, this)); +*/ + //NOTE: not really being used, so have disabled //Resource billingTriggers = getModuleResource("/scripts/onprc_billing/billing_triggers.js"); //assert billingTriggers != null; @@ -179,7 +182,7 @@ public QuerySchema createSchema(final DefaultSchema schema, Module module) @NotNull @Override - public JSONObject getPageContextJson(ContainerUser ctx) + public JSONObject getPageContextJson(ViewContext ctx) { Map ret = new HashMap<>(); Map map = getDefaultPageContextJson(ctx.getContainer()); From 4128c68ca847d8f2f44aa6ae73eabad303dfb778 Mon Sep 17 00:00:00 2001 From: Binal Date: Thu, 8 Oct 2020 00:04:19 -0700 Subject: [PATCH 14/49] Merge from onprc19.1 r.65412 to 65638 --- .../sqlserver/extscheduler-20.01-20.02.sql | 18 +++ .../sqlserver/extscheduler-20.02-20.03.sql | 7 ++ .../sqlserver/extscheduler-20.502-20.503.sql | 48 +++++++ .../extscheduler/ExtSchedulerModule.java | 2 +- .../onprc_billing/LeaseFeeRates_Final.sql | 18 +-- .../LeaseFeeReleaseAdjustment.sql | 15 +-- .../onprc_billing/leaseFeeRates_2020.sql | 119 ++++++++---------- .../onprc_billing/miscChargesWithRates.sql | 6 - .../onprc_billing/ONPRC_BillingModule.java | 13 +- .../NIHIndustryRates.query.xml | 81 ++++++------ .../NIHRateConfig.query.xml | 26 ++-- .../NIHRateSheet.query.xml | 28 ++--- .../NIHRates_ReducedFA.query.xml | 30 ++--- .../resources/etls/PotentialParent2020.xml | 42 +++++++ .../queries/study/potentialDams.query.xml | 7 ++ .../resources/queries/study/potentialDams.sql | 48 +++---- .../queries/study/potentialParents.query.xml | 8 +- .../queries/study/potentialSires.query.xml | 7 ++ .../queries/study/potentialSires.sql | 36 +++--- .../sqlserver/onprc_ehr-20.411-20.412.sql | 87 +++++++++++++ .../sqlserver/onprc_ehr-20.412-20.413.sql | 75 +++++++++++ .../sqlserver/onprc_ehr-20.413-20.414.sql | 74 +++++++++++ .../resources/views/IndustrialRatesCalc.html | 16 +-- .../views/IndustrialRatesCalc.view.xml | 2 +- onprc_ehr/resources/views/NIHRateSheet.html | 2 +- .../resources/views/NIHReducedRates.html | 2 +- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 8 +- 27 files changed, 558 insertions(+), 267 deletions(-) create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.02-20.03.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.502-20.503.sql create mode 100644 onprc_ehr/resources/etls/PotentialParent2020.xml create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.411-20.412.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.412-20.413.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.413-20.414.sql diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql new file mode 100644 index 000000000..a8024c35b --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql @@ -0,0 +1,18 @@ +/* +Created: 2020-05-07 +Created by jonesga +Purpose: To provide a resource for insert of dates into Scheduling tool + +*/ +CREATE TABLE extScheduler.Covid19Calendar(cDate datetime, cDay int, cDayOfWeek int, cDayName varchar(20), cMonth int); + +DECLARE @date date = '20200501'; +WHILE @date <= '20210430' + BEGIN + INSERT INTO Calendar VALUES (@date, + DAY(@date), + DATEPART(weekday, @date), + DATENAME(weekday, @date), + MONTH (@date)); + SET @date = DATEADD(day, 1, @date); + END \ No newline at end of file diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.02-20.03.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.02-20.03.sql new file mode 100644 index 000000000..ae7232d34 --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.02-20.03.sql @@ -0,0 +1,7 @@ +/* +Created: 2020-05-07 +Created by jonesga +Purpose: Update of Comments field of scheduler per user request + +*/ +ALTER TABLE extscheduler.Events ALTER COLUMN Comments NVARCHAR(4000); \ No newline at end of file diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.502-20.503.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.502-20.503.sql new file mode 100644 index 000000000..5a35390bb --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.502-20.503.sql @@ -0,0 +1,48 @@ +/* +Created: 2020-05-07 +Created by jonesga +Purpose: Dataset to mimic DateRange from Labkey for SCheduler actionin SQL + +*/ +DROP TABLE IF EXISTS extScheduler.DateParts +GO +CREATE TABLE extScheduler.dateParts +(date datetime, +dateOnly datetime, +DayOfYear int, +DayofMonth int, +DayofWeek int, +DayName varchar(20), + +WeekofMonth int, +WeekofYear int, + Month int, + year int) + +Go + +Insert into extScheduler.DateParts + (Date, + dateonly, + DayOfYear, + DayofMonth, + DayofWeek, + DayName, + WeekofMonth, + WeekofYear, + Month, + year) +Select + + i.NDate, + CAST(i.Ndate as date) as dateOnly, + cast(datepart(dy,i.Ndate) as integer) as DayOfYear, + cast(datepart(dd,i.Ndate) as integer) as DayOfMonth, + cast(datepart(dw,i.Ndate) as integer) as DayOfWeek, + cast(dateName(dd,i.Ndate) as VarChar(20)) as DayName, + (cast(datepart(dd,i.Ndate) as integer)/ 7) as WeekofMonth, + cast(datepart(wk,i.Ndate) as integer) as WeekofYear, + cast(datepart(mm,i.Ndate) as integer) as Month, + cast(datepart(yyyy,i.Ndate) as integer) as Year +FROM (SELECT DateAdd(dd, i.value, '5/1/2020') as NDate FROM ldk.integers i)i +Where i.nDate <= '4/20/2021' \ No newline at end of file diff --git a/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java b/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java index 3ff8a1b7e..303f70bfb 100644 --- a/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java +++ b/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java @@ -26,7 +26,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 15.31; + return 20.503; } @Override diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql index 33d04b569..159f2d300 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeRates_Final.sql @@ -1,7 +1,6 @@ --2020/02/12 build -SELECT -r.Id, +SELECT r.Id, r.date as BillingDate, r.enddate as ReleaseDate, r.CenterProject, @@ -58,29 +57,22 @@ r.canRaiseFA, r.BirthAssignment, r.BirthType, case - - When a.creditto is not null then 'Adjustment' When d.creditResource is not Null then d.creditResource Else 'p51' End as CreditTo, Case - - when a.creditto is not null then a.creditto - when d.creditResource is not Null then d.creditTo +When d.creditResource is not Null then d.creditTo else ca.account End as CreditAccount, case WHen r.releaseType = 'No Charge' then 0 - WHen r.releaseType = 'IACUC Excluded / No Charge' then 0 when r.researchOwned = 'Yes' then 0 - when r.DayLeaseLength> 0 then (r.dayleaseLength * r.CalculatedRate) - --when r.revisedRate Is Not null then 2020 - when r.assignmentType = 'automatic_adjustment' and r.revisedrate > r.CalculatedRate then (r.revisedRate - r.CalculatedRate) - when r.assignmentType = 'automatic_adjustment' then ((r.CalculatedRate - r.RevisedRate) * -1) + when r.DayLeaseLength > 0 and r.daylease = 'yes' then (r.dayleaseLength * r.CalculatedRate) + when r.revisedrate is not null and r.revisedrate > r.CalculatedRate then (r.revisedRate - r.CalculatedRate) + when r.revisedrate is not null and r.revisedrate < r.CalculatedRate then (r.CalculatedRate - r.RevisedRate) Else (1 * r.CalculatedRate) End as TotalCost, -r.calculatedRate, r.revisedRate diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql index 3b9287b01..a55bc8e42 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFeeReleaseAdjustment.sql @@ -4,14 +4,13 @@ PARAMETERS (StartDate TIMESTAMP, EndDate TIMESTAMP) SELECT a.id, case - When a.enddate <= a.dateFinalized then a.dateFinalized + When a.enddate < a.dateFinalized then a.dateFinalized Else a.enddate End as date, --a.date, a.project, a.project.project as projectID, a.project.account as alias, -(Select h.account from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.projectAccountHistory h where h.project = a.project and (a.date => h.startDate and a.date =< h.enddate)) as AliasAtTime, a.project.account.farate as faRate, a.project.account.aliastype.removesubsidy as removeSubsidy, a.project.account.aliastype.canRaiseFA as CanRaiseFA, @@ -34,11 +33,7 @@ CASE else 1 end as quantity, lf2.chargeId as leaseCharge1, -lf2.chargeID.activeRate.Subsidy as Subsidy, -(Select r3.unitcost from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRates r3 where r3.chargeID = lf2.chargeID and r3.StartDate <= a.date and r3.endDate >= a.date) as Lf1Rate, -(Select r2.unitcost from Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeRates r2 where r2.chargeID = lf.chargeID and r2.StartDate <= a.date and r2.endDate >= a.date) as Lf2Rate, lf.chargeId as leaseCharge2, -a.project.account as CreditTo, a.objectid as sourceRecord, 'Adjustment - Automatic' as chargeCategory, 'Y' as isAdjustment, @@ -52,8 +47,8 @@ a.enddatefinalized FROM Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.assignment a LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf - ON (lf.assignCondition = a.assignCondition.code - AND lf.releaseCondition = a.releaseCondition.code + ON (lf.assignCondition = a.assignCondition + AND lf.releaseCondition = a.releaseCondition AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf.minAge OR lf.minAge IS NULL) AND (a.ageAtTime.AgeAtTimeYearsRounded < lf.maxAge OR lf.maxAge IS NULL) and (a.date >=lf.startDate @@ -61,8 +56,8 @@ LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer' ) LEFT JOIN Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leaseFeeDefinition lf2 - ON (lf2.assignCondition = a.assignCondition.code - AND lf2.releaseCondition = a.projectedReleaseCondition.code + ON (lf2.assignCondition = a.assignCondition + AND lf2.releaseCondition = a.projectedReleaseCondition AND (a.ageAtTime.AgeAtTimeYearsRounded >= lf2.minAge OR lf2.minAge IS NULL) AND (a.ageAtTime.AgeAtTimeYearsRounded < lf2.maxAge OR lf2.maxAge IS NULL) and (a.date >=lf2.startDate diff --git a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql index 9a7bb5d27..b789728c6 100644 --- a/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql +++ b/onprc_billing/resources/queries/onprc_billing/leaseFeeRates_2020.sql @@ -1,49 +1,51 @@ --Corrested Issue with Adjustments and loading into Test --20200111 - changed source from rate data to a passthru with a lookup of rate name and unit cost -SELECT r.Id, +SELECT d.Id, r.leasetype, - r.ResearchOwned, - r.projectID, --integer - r.CenterProject, + d.ResearchOwned, + d.project, --integer + d.project.name as CenterProject, r.AliasAtTime, - r.AgeAtTime as AgeAtAssignment, - r.ageinyears, - r.AgeGroup, - r.BirthAssignment, - r.BirthType, - r.AssignmentType, - r.DayLease, - r.DayLeaseLength, --integer - r.MultipleAssignments, - r.CreditResource as dualassignment, - r.creditto, - r.assignmentdate, - r.projectedRelease, - r.releasedate, - r.datefinalized, - r.code as assignCondition, --integer - r.ProjectedReleaseCode as projectedReleaseCondition, --integer - r.releaseCondition, --integer - r.releaseType, - r.remark, - r.Currentalias, - r.farate, - r.removesubsidy, - r.canRaiseFA, + d.AgeAtAssignment, + d.ageinyears, + d.AgeGroup, + d.BirthAssignment, + d.BirthType, + d.AssignmentType, + d.DayLease, + d.DayLeaseLength, --integer + d.MultipleAssignments, + d.CreditResource as dualassignment, + null as creditto, + d.date, + d.projectedRelease, + d.enddate, + d.datefinalized, + d.assignCondition, --integer + d.projectedReleaseCondition, --integer + d.releaseCondition, --integer + d.releaseType, + d.remark, + d.alias, + d.farate, + d.removesubsidy, + d.canRaiseFA, r.ChargeID, --integer - r.ChargeItem as Item, - r.ServiceCenter, + i.Name as Item, + i.DepartmentCode as ServiceCenter, r.exemptionRate, r.Multiplier, r.subsidy, - RateCalc(r.AliasAtTime,r.chargeID,r.projectID,r.assignmentDate,r.subsidy) as CalculatedRate, + RateCalc(r.AliasAtTime,r.chargeID,d.project,d.Date,.4) as CalculatedRate, null as revisedRate, r.revisedChargeID, r.revisedSubsidy -FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateChargeItem r - +FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_rateChargeItem r join + Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.LeaseFee_Demographics d on r.id = d.id and r.assignmentdate = d.date and r.projectid = d.project + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.leasefee_LeaseType t on d.id = t.id and t.assignmentdate = d.date and t.project = d.project + join Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.chargeableItems i on i.rowID = r.chargeID union @@ -53,7 +55,7 @@ select a.researchowned, a.projectID, --intege a.project.name as CenterProject, - a.aliasAtTime, + a.alias, a.ageattime, 1 as ageinYears, --need to run function to return years '' as agegroup, @@ -61,11 +63,11 @@ select '' as BirthType, 'automatic_adjustment' as AssignmentTypeNA, '' as DayLease, - 1 as DayLeaseLength, --integer + '' as DayLeaseLength, --integer '' as MultipleAssignments, null as dualassignment, - a.creditto, - a.enddate as BillingDate, + null as creditto, + a.date, a.enddate as projectedrelease, a.enddate, a.datefinalized, @@ -83,25 +85,9 @@ select ii.DepartmentCode as ServiceCenter, null as exemptionRate, null as Multiplier, - ii.activeRate.subsidy, - case - when a.dateFinalized < '5/1/2015' then 0 - when a.projectID = 1106 then 0 - When (a.removesubsidy = 'false' and a.canRaiseFa = 'false') then a.lf2rate - When (a.removesubsidy = 'true' or a.CanRaiseFa = 'true') then RateCalc(a.aliasAtTime,a.leasecharge1,a.projectID,a.assignmentStart,ii.activeRate.subsidy) - When (a.removesubsidy = 'false' or a.CanRaiseFa = 'true') then RateCalc(a.aliasAtTime,a.leasecharge1,a.projectID,a.assignmentStart,ii.activeRate.subsidy) - --Else RateCalc(a.aliasatTime,a.leasecharge2,a.projectID,a.enddate,ii.activeRate.subsidy) - else a.lf2rate - End as CalculatedRate, - - case - when a.dateFinalized < '5/1/2015' then 0 - when a.projectID = 1106 then 0 - When (a.removesubsidy = 'false' or a.canRaiseFa = 'false') then a.lf2Rate - - - Else RateCalc(a.aliasatTime,a.leasecharge2,a.projectID,a.enddate,a.subsidy) - End as RevisedRate, + null as subsidy, + RateCalc(a.alias,a.leasecharge1,a.projectID, a.date,a.farate) as CalculatedRate, + RateCalc(a.alias,a.leasecharge2,a.projectID, a.date,a.farate) as RevisedRate, a.leaseCharge2, null as RevisedSubsidy @@ -145,19 +131,16 @@ Select r.comment as remark, null as alias2, null as farate, - r.removesubsidy, - r.canRaiseFA, + null as removesubsidy, + null as canRaiseFA, r.chargeID, --integer - - r.chargeID.Name as Item, - r.serviceCenter as ServiceCenter, - ' ' as IsExemption, - --Cast(r.isExemption as Float) as IsExemption, - r.PM_Multiplier, - r.chargeID.activeRate.Subsidy as Subsidy, - --' ' as Ratecalc, - RateCalc(r.account,r.charge_ID,r.projectID,r.Date,r.subsidy) as CalculatedRate, + r.serviceCenter as ServiceCenter, + null as exemptionRate, + Null as Multiplier, + null as Subsidy, + + r.rateCalc, null as RevisedRate, null as rate2, null as RevisedSubsidy @@ -166,4 +149,4 @@ Select FROM Site.{substitutePath moduleProperty('onprc_billing','BillingContainer')}.onprc_billing.miscChargesWithRates r WHERE cast(r.billingDate as date) >= CAST(StartDate as date) AND cast(r.billingDate as date) <= CAST(EndDate as date) -AND r.category IN ('Lease Fees') \ No newline at end of file +AND r.category IN ('Lease Fees', 'Lease Setup Fee', 'Lease Setup Fees') diff --git a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql index 51bcc8189..ffe18c7fd 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql +++ b/onprc_billing/resources/queries/onprc_billing/miscChargesWithRates.sql @@ -7,9 +7,6 @@ SELECT COALESCE(p.debitedaccount, aliasAtTime.account) as account, p.chargetype, p.chargeId, - p.chargeId.rowid as Charge_ID, - cr.chargeID.activeRate.subsidy as subsidy, - p.project.project as ProjectID, COALESCE(p.chargetype.servicecenter, p.chargeId.departmentCode) as serviceCenter, coalesce(p.chargeId.name, p.item) as item, p.unitCost as MCEnteredUnitCost, @@ -59,9 +56,6 @@ SELECT p.created, p.createdby, p.taskId, - alias.aliasType.removeSubsidy as removeSubsidy, - pm.multiplier as PM_Multiplier, - alias.aliasType.canRaiseFA as canRaiseFa, coalesce(p.creditedaccount, cu.account, ce.account) as creditAccount, CASE WHEN (cu.account IS NOT NULL) THEN 'Charge Unit' ELSE 'Chargeable Item' END as creditAccountType, diff --git a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java index da247a92e..a5557ca1f 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java +++ b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java @@ -12,7 +12,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - Cleanupo of file 4/11/2020 */ package org.labkey.onprc_billing; @@ -39,11 +38,13 @@ import org.labkey.api.security.roles.RoleManager; import org.labkey.api.view.ViewContext; import org.labkey.api.view.WebPartFactory; +import org.labkey.api.writer.ContainerUser; import org.labkey.onprc_billing.button.ChangeBillDateButton; import org.labkey.onprc_billing.button.ChargeEditButton; import org.labkey.onprc_billing.button.ProjectEditButton; import org.labkey.onprc_billing.dataentry.ChargesAdvancedFormType; import org.labkey.onprc_billing.dataentry.ChargesFormType; +//import org.labkey.onprc_billing.dataentry.ChargesVirologyCoreFormType; import org.labkey.onprc_billing.dataentry.ChargesVirologyCoreFormType; import org.labkey.onprc_billing.dataentry.ReversalFormType; import org.labkey.onprc_billing.notification.BillingValidationNotification; @@ -75,11 +76,11 @@ public String getName() { return NAME; } - +//This was updated to match all sets @Override public @Nullable Double getSchemaVersion() { - return 20.411; + return 19.411; } @Override @@ -125,10 +126,6 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext) //Added: 5/6/2018 Kollil EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ChargesVirologyCoreFormType.class, this)); - //Added: 1/6/2020 Kollil - /* EHRService.get().registerFormType(new DefaultDataEntryFormFactory(ChargesARTCoreFormType.class, this)); -*/ - //NOTE: not really being used, so have disabled //Resource billingTriggers = getModuleResource("/scripts/onprc_billing/billing_triggers.js"); //assert billingTriggers != null; @@ -182,7 +179,7 @@ public QuerySchema createSchema(final DefaultSchema schema, Module module) @NotNull @Override - public JSONObject getPageContextJson(ViewContext ctx) + public JSONObject getPageContextJson(ContainerUser ctx) { Map ret = new HashMap<>(); Map map = getDefaultPageContextJson(ctx.getContainer()); diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml index b4f6e1977..6994f26e1 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml @@ -1,4 +1,5 @@ - + +query xmlns="http://labkey.org/data/xml/query"> @@ -6,58 +7,56 @@ NIH Industrial Rates - - - - Current Year - $#,##0.00xzs - - - - - - YR61: 5/1/20 to 4/30/21 - $#,##0.00 - - - YR62: 5/1/21 to 4/30/22 - $#,##0.00 - - - YR63: 5/1/22 to 4/30/23 - $#,##0.00 - - - YR64: 5/1/23 to 4/30/24 - $#,##0.00 - + + + + Current Year + $#,##0.00 + - - YR65: 5/1/24 to 4/30/25 - $#,##0.00 - + + YR62: 5/1/21 to 4/30/22 + $#,##0.00 + + + YR63: 5/1/22 to 4/30/23 + $#,##0.00 + + + YR64: 5/1/23 to 4/30/24 + $#,##0.00 + + + YR65: 5/1/24 to 4/30/25 + $#,##0.00 + + + YR66: 5/1/25 to 4/30/26 + $#,##0.00 + - YR66: 5/1/25 to 4/30/26 + YR67: 5/1/26 to 4/30/27 $#,##0.00 + - YR67: 5/1/26 to 4/30/27 + YR68: 5/1/27 to 4/30/28 + $#,##0.00 + + + YR69: 5/1/28 to 4/30/29 $#,##0.00 - - - - - - Posted Date - MM/dd/yyyy - + + Posted Date + MM/dd/yyyy + - +
    diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml index 2a4826204..943a1fd76 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateConfig.query.xml @@ -13,50 +13,42 @@ $#,##0.00
    - - - - - - YR60: 5/1/19 to 4/30/20 + YR62: 5/1/21 to 4/30/22 $#,##0.00 - YR61: 5/1/20 to 4/30/21 + YR63: 5/1/22 to 4/30/23 $#,##0.00 - YR62: 5/1/21 to 4/30/22 + YR64: 5/1/23 to 4/30/24 $#,##0.00 - YR63: 5/1/22 to 4/30/23 + YR65: 5/1/24 to 4/30/25 $#,##0.00 - YR64: 5/1/23 to 4/30/24 + YR66: 5/1/25 to 4/30/26 $#,##0.00 - YR65: 5/1/24 to 4/30/25 + YR67: 5/1/26 to 4/30/27 $#,##0.00 - YR66: 5/1/25 to 4/30/26 + YR68: 5/1/27 to 4/30/28 $#,##0.00 - YR67: 5/1/26 to 4/30/27 + YR69: 5/1/28 to 4/30/29 $#,##0.00 - - - - + Posted Date diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml index 94628e3e6..c65f15585 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRateSheet.query.xml @@ -8,7 +8,7 @@ - + Current Year $#,##0.00 @@ -18,47 +18,42 @@ - - YR61: 5/1/20 to 4/30/21 + YR62: 5/1/21 to 4/30/22 $#,##0.00 - YR62: 5/1/21 to 4/30/22 + YR63: 5/1/22 to 4/30/23 $#,##0.00 - YR63: 5/1/22 to 4/30/23 + YR64: 5/1/23 to 4/30/24 $#,##0.00 - YR64: 5/1/23 to 4/30/24 + YR65: 5/1/24 to 4/30/25 $#,##0.00 - - YR65: 5/1/24 to 4/30/25 + YR66: 5/1/25 to 4/30/26 $#,##0.00 - YR66: 5/1/25 to 4/30/26 + YR67: 5/1/26 to 4/30/27 $#,##0.00 + - YR67: 5/1/26 to 4/30/27 + YR68: 5/1/27 to 4/30/28 $#,##0.00 - - YR67: 5/1/27 to 4/30/28 + YR69: 5/1/28 to 4/30/29 $#,##0.00 - - - - + Posted Date @@ -66,7 +61,6 @@ - diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml index 954e124e3..9afb7bc29 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.query.xml @@ -13,47 +13,43 @@ $#,##0.00 - - - - - - - YR61: 5/1/20 to 4/30/21 + YR62: 5/1/21 to 4/30/22 $#,##0.00 - YR62: 5/1/21 to 4/30/22 + YR63: 5/1/22 to 4/30/23 $#,##0.00 - YR63: 5/1/22 to 4/30/23 + YR64: 5/1/23 to 4/30/24 $#,##0.00 - YR64: 5/1/23 to 4/30/24 + YR65: 5/1/24 to 4/30/25 $#,##0.00 - - YR65: 5/1/24 to 4/30/25 + YR66: 5/1/25 to 4/30/26 $#,##0.00 - YR66: 5/1/25 to 4/30/26 + YR67: 5/1/26 to 4/30/27 $#,##0.00 + - YR67: 5/1/26 to 4/30/27 + YR68: 5/1/27 to 4/30/28 + $#,##0.00 + + + YR69: 5/1/28 to 4/30/29 $#,##0.00 + Posted Date MM/dd/yyyy diff --git a/onprc_ehr/resources/etls/PotentialParent2020.xml b/onprc_ehr/resources/etls/PotentialParent2020.xml new file mode 100644 index 000000000..0e82fa1bc --- /dev/null +++ b/onprc_ehr/resources/etls/PotentialParent2020.xml @@ -0,0 +1,42 @@ + + + + + + + + PotentialParentUpdate + + Executes Stored Procedutres to Populate Potential Parent Datasets + + + + + + + Runs a stored procedure to Update Potential Dam for Prime. + + + + + + Runs a stored procedure to Update Potential Sire for Prime + + + + + + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/queries/study/potentialDams.query.xml b/onprc_ehr/resources/queries/study/potentialDams.query.xml index fbe016be9..43404963f 100644 --- a/onprc_ehr/resources/queries/study/potentialDams.query.xml +++ b/onprc_ehr/resources/queries/study/potentialDams.query.xml @@ -5,6 +5,13 @@ Potential Dams This query identifies all female animals co-housed in the same room/cage at time of birth + + + study + animal + Id + + Dam Age At Birth (years) diff --git a/onprc_ehr/resources/queries/study/potentialDams.sql b/onprc_ehr/resources/queries/study/potentialDams.sql index 274277796..17b9e8362 100644 --- a/onprc_ehr/resources/queries/study/potentialDams.sql +++ b/onprc_ehr/resources/queries/study/potentialDams.sql @@ -1,40 +1,22 @@ /* * Copyright (c) 2013-2014 LabKey Corporation * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Updated 2020-04-23 by jones ga + * changed the source to a insert from a stored procedure */ SELECT - b.Id, - b.date as birth, - h.Id as potentialDam, - b.room as birthRoom, - b.cage as birthCage, - --NOTE: SQL_TSI_YEAR not support in postgres - (timestampdiff('SQL_TSI_DAY', h.Id.demographics.birth, b.date) / 365) as damAgeAtTime - -FROM study.birth b - -JOIN study.housing h ON ( - (b.Id != h.Id AND - h.dateOnly <= b.dateOnly AND - h.enddateCoalesced >= b.dateOnly AND - h.room = b.room AND (h.cage = b.cage OR (h.cage is null and b.cage is null)) - ) - --note: this is to always include observed parents - OR h.Id = b.dam -) + d.RowId, + d.participantId as id, + d.Date as birth, + d.Species, + d.room as birthroom, + d.cage as birthCage, + d.DamAgeAtTime, + d.potentialDam, + d.DamBirth, + d.Damgender, + d.DamSpecies, + d.DamDeath -WHERE h.id.demographics.gender = 'f' and timestampdiff('SQL_TSI_DAY', h.Id.demographics.birth, b.date) > 912.5 --(2.5 years) -AND h.Id.demographics.species = b.Id.demographics.species +from onprc_ehr.PotentialDam_source d -GROUP BY b.Id, b.date, b.room, b.cage, h.Id, h.Id.demographics.birth \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/potentialParents.query.xml b/onprc_ehr/resources/queries/study/potentialParents.query.xml index f6ce229cb..6e843cfd5 100644 --- a/onprc_ehr/resources/queries/study/potentialParents.query.xml +++ b/onprc_ehr/resources/queries/study/potentialParents.query.xml @@ -4,7 +4,13 @@ Potential Parents - + + + study + animal + Id + +
    diff --git a/onprc_ehr/resources/queries/study/potentialSires.query.xml b/onprc_ehr/resources/queries/study/potentialSires.query.xml index 5f1b81e96..cc201d872 100644 --- a/onprc_ehr/resources/queries/study/potentialSires.query.xml +++ b/onprc_ehr/resources/queries/study/potentialSires.query.xml @@ -4,6 +4,13 @@ Potential Sires + + + study + animal + Id + + Sire Age At Conception Window (years) diff --git a/onprc_ehr/resources/queries/study/potentialSires.sql b/onprc_ehr/resources/queries/study/potentialSires.sql index a00af8b5e..f20548692 100644 --- a/onprc_ehr/resources/queries/study/potentialSires.sql +++ b/onprc_ehr/resources/queries/study/potentialSires.sql @@ -13,29 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -SELECT - c.Id, - h.Id as potentialSire, - group_concat(DISTINCT h.room) as rooms, - group_concat(DISTINCT h.cage) as cages, - --NOTE: SQL_TSI_YEAR not support in postgres - (max(timestampdiff('SQL_TSI_DAY', h.Id.demographics.birth, c.minDate)) / 365) as sireAgeAtTime - -FROM study.potentialConceptionLocations c ---then find all males overlapping with these locations that also overlap with the conception window -JOIN study.housing h ON (( - h.Id.demographics.gender = 'm' AND - h.room = c.room AND - (h.cage = c.cage OR (h.cage IS NULL AND c.cage IS NULL)) AND - h.dateOnly <= cast(c.maxDate as date) AND h.enddateCoalesced >= cast(c.minDate as date) -) +SELECT + d.RowId, + d.participantId as id, + d.Date as Birth, + d.Species, + d.room as birthRooom, + d.cage as birthCage, + d.sireAgeAtTime, + d.potentialSire, + d.SireBirth, + d.Siregender, + d.SireSpecies, + d.SireDeath ---note: this is to always include all observed sires -OR h.Id = c.Id.birth.sire -) +from onprc_ehr.PotentialSire_source d -WHERE timestampdiff('SQL_TSI_DAY', h.Id.demographics.birth, c.minDate) > 912.5 --(2.5 years) -AND h.Id.demographics.species = c.Id.demographics.species -GROUP BY c.Id, h.Id \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.411-20.412.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.411-20.412.sql new file mode 100644 index 000000000..6930c55ca --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.411-20.412.sql @@ -0,0 +1,87 @@ +/****** Object: Table [onprc_ehr].[PotentialSire_source] Script Date: 4/121/20202 7:00:04 AM ******/ +/****** Object: Table [onprc_ehr].[PotentialDam_source] Script Date: 4/121/20202 7:00:04 AM ******/ +/****** Object: Table [onprc_ehr].[PotentialParents_source] Script Date: 4/121/20202 7:00:04 AM ******/ + +DROP TABLE IF EXISTS [onprc_ehr].[potentialDam_Source] +GO + +DROP TABLE IF EXISTS [onprc_ehr].[potentialsire_Source] +GO + +DROP TABLE IF EXISTS [onprc_ehr].[potentialParents_Source] +GO + + + +/****** Object: Table [onprc_ehr].[PotentialSire_source] Script Date: 4/121/20202 7:00:04 AM ******/ +CREATE TABLE [onprc_ehr].[PotentialSire_source]( + [RowId] INT IDENTITY(1,1)NOT NULL, + [participantId] [nvarchar](32) NULL, + [Date] [datetime] NULL, + [Species] [nvarchar](100) NULL, + [room][nvarchar](100) NULL, + [cage][nvarchar](100) NULL, + [SireAgeAtTime] [datetime] NULL, + [PotentialSire] [nvarchar](100) NULL, + [SireBirth] [datetime] NULL, + [Siregender] [nvarchar](100) NULL, + [Sirespecies] [nvarchar](100) NULL, + [SireDeath] [datetime] NULL, + [created] [datetime] NULL, + [createdBy] [int] NULL, + [modified] [datetime] NULL, + [modifiedBy] [int] NULL, + [container] ENTITYID + + CONSTRAINT pk_potentialSire PRIMARY KEY (rowID) +) + + +/****** Object: Table [onprc_ehr].[PotentialSire_source] Script Date: 4/121/20202 7:00:04 AM ******/ +CREATE TABLE [onprc_ehr].[PotentialDam_source]( + [RowId] INT IDENTITY(1,1)NOT NULL, + [participantId] [nvarchar](32) NULL, + [Date] [datetime] NULL, + [Species] [nvarchar](100) NULL, + [room][nvarchar](100) NULL, + [cage][nvarchar](100) NULL, + [DamAgeAtTime] [datetime] NULL, + [PotentialDam] [nvarchar](100) NULL, + [DamBirth] [datetime] NULL, + [Damgender] [nvarchar](100) NULL, + [DamSpecies] [nvarchar](100) NULL, + [DamDeath] [datetime] NULL, + [created] [datetime] NULL, + [createdBy] [int] NULL, + [modified] [datetime] NULL, + [modifiedBy] [int] NULL, + [container] ENTITYID + + CONSTRAINT pk_potentialDam PRIMARY KEY (rowID) +) + + + +/****** Object: Table [onprc_ehr].[PotentialParents_source] Script Date: 4/121/20202 7:00:04 AM ******/ +CREATE TABLE [onprc_ehr].[PotentialParents_source]( + [RowId] INT IDENTITY(1,1)NOT NULL, + [participantId] [nvarchar](32) NULL, + [BirthDate] [datetime] NULL, + [Species] [nvarchar](100) NULL, + [BirthRoom][nvarchar](100) NULL, + [Birthcage][nvarchar](100) NULL, + [ParentAgeAtTime] [datetime] NULL, + [PotentialParent] [nvarchar](100) NULL, + [[PotentialParentType] [nvarchar](100) NULL, + [ParentBirth] [datetime] NULL, + [Parentgender] [nvarchar](100) NULL, + [ParentSpecies] [nvarchar](100) NULL, + [ParentDeath] [datetime] NULL, + [created] [datetime] NULL, + [createdBy] [int] NULL, + [modified] [datetime] NULL, + [modifiedBy] [int] NULL, + [container] ENTITYID + + CONSTRAINT pk_potentialParent PRIMARY KEY (rowID) +) \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.412-20.413.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.412-20.413.sql new file mode 100644 index 000000000..23bca7399 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.412-20.413.sql @@ -0,0 +1,75 @@ + +/****** Object: StoredProcedure [onprc_ehr].[PotentialDam_Insert] Script Date: 4/22/2020 10:16:00 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ============================================= +-- Author: jonesga@ohsu.edu +-- Create date: 2020-04-22 +-- Description: SP runs a query to populate the Potential Sire Dataset +-- ============================================= + CREATE PROCEDURE [onprc_ehr].[PotentialDam_Insert] + + AS + BEGIN + --Potential Sire Query +--This will be used in generation of potential parents + Truncate table [onprc_ehr].[PotentialDam_source] + INSERT INTO [onprc_ehr].[PotentialDam_source] + ([participantId] + ,[Date] + ,[Species] + ,[room] + ,[cage] + ,[DamAgeAtTime] + ,[PotentialDam] + ,[DamBirth] + ,[Damgender] + ,[DamSpecies] + ,[DamDeath] + ,[created] + ,[createdBy] + ,[modified] + ,[modifiedBy] + ,[container] + ) + select + b.participantid, + b.date, + b.species, + b.room, + b.cage, + DateDiff(day, d.birth, b.date) / 365 as SireAgeAtTime, +-- (timestampdiff('SQL_TSI_DAY', h.Id.demographics.birth, b.date) / 365) as damAgeAtTime +-- we want a list of potential dams that were of age at the time of the infants birth +-- So look at the housing table match the Room and Cage on that date + h.participantID, + d.birth as SireBirth, + d.gender, + d.species, + d.death as SireDeath, + GETDATE(), + 1011, + GetDate(), + 1011, + 'CD17027B-C55F-102F-9907-5107380A54BE' + from [studyDataset].[c6d202_birth] b + join [studyDataset].[c6d194_housing] h on + (b.participantId != h.participantId AND + (h.date <= b.date AND h.enddate >= b.date) AND + h.room = b.room AND (h.cage = b.cage OR (h.cage is null and b.cage is null)) + --note: this is to always include observed parents + OR h.participantid = b.dam + ) + join [studyDataset].[c6d203_demographics] d on d.participantid = h.participantid + join [studyDataset].[c6d203_demographics] d1 on d1.participantID = b.participantid + WHERE d.gender = 'm' and DateDiff(day, d.birth, b.date) > 912.5 --(2.5 years) + AND d.species = d1.species + + + + + + + END diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.413-20.414.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.413-20.414.sql new file mode 100644 index 000000000..1c46590f3 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.413-20.414.sql @@ -0,0 +1,74 @@ + +/****** Object: StoredProcedure [onprc_ehr].[PotentialSire_Insert] Script Date: 4/22/2020 10:16:39 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ============================================= +-- Author: jonesga@ohsu.edu +-- Create date: 2020-04-22 +-- Description: SP runs a query to populate the Potential Sire Dataset +-- ============================================= + + +CREATE PROCEDURE [onprc_ehr].[PotentialSire_Insert] + + AS + BEGIN + --Potential Sire Query +--This will be used in generation of potential parents + Truncate table [onprc_ehr].[PotentialSire_source] + INSERT INTO [onprc_ehr].[PotentialSire_source] + ([participantId] + ,[Date] + ,[Species] + ,[room] + ,[cage] + ,[SireAgeAtTime] + ,[PotentialSire] + ,[sireBirth] + ,[siregender] + ,[sireSpecies] + ,[SireDeath] + ,[created] + ,[createdBy] + ,[modified] + ,[modifiedBy] + ,[container] + ) + select + b.participantid, + b.date, + b.species, + b.room, + b.cage, + DateDiff(day, d.birth, b.date) / 365 as SireAgeAtTime, + h.participantID, + d.birth as SireBirth, + d.gender, + d.species, + d.death as SireDeath, + GETDATE(), + 1011, + GetDate(), + 1011, + 'CD17027B-C55F-102F-9907-5107380A54BE' + from [studyDataset].[c6d202_birth] b + join [studyDataset].[c6d194_housing] h on + (b.participantId != h.participantId AND + (h.date <= b.date AND h.enddate >= b.date) AND + h.room = b.room AND (h.cage = b.cage OR (h.cage is null and b.cage is null)) + --note: this is to always include observed parents + OR h.participantid = b.dam + ) + join [studyDataset].[c6d203_demographics] d on d.participantid = h.participantid + join [studyDataset].[c6d203_demographics] d1 on d1.participantID = b.participantid + WHERE d.gender = 'm' and DateDiff(day, d.birth, b.date) > 912.5 --(2.5 years) + AND d.species = d1.species + + + + + + + END diff --git a/onprc_ehr/resources/views/IndustrialRatesCalc.html b/onprc_ehr/resources/views/IndustrialRatesCalc.html index f9cddde69..e493d6a14 100644 --- a/onprc_ehr/resources/views/IndustrialRatesCalc.html +++ b/onprc_ehr/resources/views/IndustrialRatesCalc.html @@ -19,11 +19,11 @@ }, layout: {type: 'vbox'}, items: [{ - html: 'Please Select the Calculation Method to Use from the Drop Down Box. If Margin is included enter a value between .0 and and .50 Please use a 2 place decimal', + html: 'Please Select the Calculation Method to Use from the Drop Down Box. If Margin is included enter a value between .0 and and .50. Please use a 2 place decimal. THE ONPRC F&A Rate is 47% ', style: 'padding-bottom: 10px;' }, - { + {E xtype: 'numberfield', itemId: 'filter-field', fieldLabel: 'Project Margin', @@ -37,7 +37,7 @@ { xtype: 'button', - text: 'Retrieve Industry Rates -------Margin Only ', + text: 'Retrieve Industry Rates ------- Margin Only ', border: true, padding: '10 5 3 10', // (top, right, bottom, left). handler: function (btn) { @@ -46,7 +46,7 @@ if ((cushionValue != null) &&(cushionValue >= .0) && (cushionValue <= .50)) { var qwp = new LABKEY.QueryWebPart({ schemaName: 'onprc_billing_public', - queryName: 'NIHIndustryRateNew', + queryName: 'NIHIndustryRates', renderTo: 'IndustryDiv', title: 'Industry Rates', parameters: {Margin: cushionValue, FARate: 1, CalcMethod: 'Margin Only'} @@ -60,7 +60,7 @@ }, { xtype: 'button', - text: 'Retrieve Industry Rates ----------F&A Only ', + text: 'Retrieve Industry Rates ---------- F&A Only ', border: true, padding: '10 11 3 10', // (top, right, bottom, left). handler: function (btn) { @@ -70,7 +70,7 @@ var qwp = new LABKEY.QueryWebPart({ schemaName: 'onprc_billing_public', - queryName: 'NIHIndustryRateNew', + queryName: 'NIHIndustryRates', renderTo: 'IndustryDiv', title: 'Industry Rates', @@ -91,7 +91,7 @@ if ((cushionValue != null) &&(cushionValue >= .0) && (cushionValue <= .50)) { var qwp = new LABKEY.QueryWebPart({ schemaName: 'onprc_billing_public', - queryName: 'NIHIndustryRateNew', + queryName: 'NIHIndustryRates', renderTo: 'IndustryDiv', title: 'Industry Rates', parameters: {Margin: cushionValue, FARate: 1, CalcMethod: 'Margin and F & A'} @@ -116,7 +116,7 @@ var qwp = new LABKEY.QueryWebPart({ schemaName: 'onprc_billing_public', - queryName: 'NIHIndustryRateNew', + queryName: 'NIHIndustryRates', renderTo: 'IndustryDiv', title: 'Industry Rates', parameters: {Margin: 0, FARate: 1, CalcMethod: 'No Margin or F&A Calc '} diff --git a/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml b/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml index eeed2e4dd..cbaba6594 100644 --- a/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml +++ b/onprc_ehr/resources/views/IndustrialRatesCalc.view.xml @@ -1,4 +1,4 @@ - + diff --git a/onprc_ehr/resources/views/NIHRateSheet.html b/onprc_ehr/resources/views/NIHRateSheet.html index a2931a09b..b83614913 100644 --- a/onprc_ehr/resources/views/NIHRateSheet.html +++ b/onprc_ehr/resources/views/NIHRateSheet.html @@ -16,7 +16,7 @@ var config= { renderTo: 'qwpDiv', schemaName: 'onprc_billing_public', - queryName: 'NIHRateSheetYr60', + queryName: 'NIHRateSheet', buttonBarPosition: 'top', allowChooseQuery: false, diff --git a/onprc_ehr/resources/views/NIHReducedRates.html b/onprc_ehr/resources/views/NIHReducedRates.html index 2ccc082ff..4de79a8e8 100644 --- a/onprc_ehr/resources/views/NIHReducedRates.html +++ b/onprc_ehr/resources/views/NIHReducedRates.html @@ -46,7 +46,7 @@ Ext4.create('Ext.form.FormPanel', { renderTo : 'theFormDiv', bodyStyle: 'padding: 5px;', - queryName: 'NIHRates_ReducedFANew', + queryName: 'NIHRates_ReducedFA', title : 'Reduced F&A Rates: Enter the Project F&A Percentage To Use', defaults: { border: false diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 53649494d..4a418588d 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -87,6 +87,7 @@ import org.labkey.onprc_ehr.security.ONPRC_EHRCMUAdministrationRole; import org.labkey.onprc_ehr.security.ONPRC_EHRCustomerEditPermission; import org.labkey.onprc_ehr.security.ONPRC_EHRCustomerEditRole; +//import org.labkey.onprc_ehr.security.ONPRC_EHRPMICEditRole; import org.labkey.onprc_ehr.security.ONPRC_EHRTransferRequestRole; import org.labkey.onprc_ehr.table.ONPRC_EHRCustomizer; @@ -114,7 +115,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 20.107; + return 20.414; } @Override @@ -131,6 +132,9 @@ protected void init() RoleManager.registerRole(new ONPRC_EHRCustomerEditRole()); RoleManager.registerRole(new ONPRC_EHRCMUAdministrationRole()); RoleManager.registerRole(new ONPRC_EHRTransferRequestRole()); + +// Added: 12-5-2019 +// RoleManager.registerRole(new ONPRC_EHRPMICEditRole()); } @Override @@ -442,7 +446,7 @@ public String toString() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(LabworkRequestBulkEditFormType.class, this)); //Added: 5/23/2019 Kolli - // EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PMICRequestFormType.class, this)); +// EHRService.get().registerFormType(new DefaultDataEntryFormFactory(PMICRequestFormType.class, this)); //Added: 8/10/2019 Kolli // EHRService.get().registerFormType(new DefaultDataEntryFormFactory(IPCRequestFormType.class, this)); From e9cdb74147d845ee8ae93f28b1c50ee5f78ed603 Mon Sep 17 00:00:00 2001 From: Binal Date: Thu, 8 Oct 2020 00:11:06 -0700 Subject: [PATCH 15/49] Merge from onprc19.1 r.65639 to 65677 --- .../sqlserver/extscheduler-20.01-20.02.sql | 18 --- .../sqlserver/extscheduler-20.503-20.504.sql | 55 +++++++ .../sqlserver/extscheduler-20.504-20.505.sql | 61 ++++++++ .../sqlserver/extscheduler-20.505-20.506.sql | 61 ++++++++ .../sqlserver/extscheduler-20.601-20.602.sql | 30 ++++ .../sqlserver/extscheduler-20.602-20.603.sql | 29 ++++ .../web/extscheduler/App/view/EventForm.js | 16 +- .../extscheduler/ExtSchedulerModule.java | 3 +- .../extscheduler/query/EventsTable.java | 14 +- onprc_billing/resources/etls/ogaSynch2019.xml | 67 --------- .../resources/etls/ogaSynchDataOnly.xml | 30 ---- .../resources/etls/ogaSynchOnlyUAT.xml | 30 ---- .../onprc_billing/ActiveAlias_2020.query.xml | 78 ++++++++++ .../onprc_billing/Activealias_2020.sql | 39 +++++ .../queries/onprc_billing/aliases/.qview.xml | 12 +- .../onprc_billing/oga_AliasCleanup2020.sql | 80 ++++++++++ .../onprc_billing/procedureFeeDefinition.js | 4 +- .../sqlserver/onprc_billing-20.104-20.105.sql | 39 +++++ .../sqlserver/onprc_billing-20.508-20.509.sql | 39 +++++ .../sqlserver/onprc_billing-20.511-20.512.sql | 21 +++ .../sqlserver/onprc_billing-20.512-20.513.sql | 86 +++++++++++ .../sqlserver/onprc_billing-20.514-20.515.sql | 105 +++++++++++++ .../resources/schemas/onprc_billing.xml | 7 + .../resources/etls/extSchedulerCovid19.xml | 41 +++++ .../resources/etls/ogaAliasCleanup2020.xml | 25 ++++ .../resources/etls/ogaSynch2020.xml | 0 .../scripts/onprc_ehr/onprc_triggers.js | 4 +- .../resources/views/Covid19Scheduler.html | 50 +++++++ .../views/Covid19Scheduler.webpart.xml | 6 + .../resources/views/Covie19Scheduler.view.xml | 6 + .../ColonyAlertsNotification.java | 140 +----------------- 31 files changed, 900 insertions(+), 296 deletions(-) delete mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.503-20.504.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.601-20.602.sql create mode 100644 extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.602-20.603.sql delete mode 100644 onprc_billing/resources/etls/ogaSynch2019.xml delete mode 100644 onprc_billing/resources/etls/ogaSynchDataOnly.xml delete mode 100644 onprc_billing/resources/etls/ogaSynchOnlyUAT.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/ActiveAlias_2020.query.xml create mode 100644 onprc_billing/resources/queries/onprc_billing/Activealias_2020.sql create mode 100644 onprc_billing/resources/queries/onprc_billing/oga_AliasCleanup2020.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.104-20.105.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.508-20.509.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql create mode 100644 onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql create mode 100644 onprc_ehr/resources/etls/extSchedulerCovid19.xml create mode 100644 onprc_ehr/resources/etls/ogaAliasCleanup2020.xml rename {onprc_billing => onprc_ehr}/resources/etls/ogaSynch2020.xml (100%) create mode 100644 onprc_ehr/resources/views/Covid19Scheduler.html create mode 100644 onprc_ehr/resources/views/Covid19Scheduler.webpart.xml create mode 100644 onprc_ehr/resources/views/Covie19Scheduler.view.xml diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql deleted file mode 100644 index a8024c35b..000000000 --- a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.01-20.02.sql +++ /dev/null @@ -1,18 +0,0 @@ -/* -Created: 2020-05-07 -Created by jonesga -Purpose: To provide a resource for insert of dates into Scheduling tool - -*/ -CREATE TABLE extScheduler.Covid19Calendar(cDate datetime, cDay int, cDayOfWeek int, cDayName varchar(20), cMonth int); - -DECLARE @date date = '20200501'; -WHILE @date <= '20210430' - BEGIN - INSERT INTO Calendar VALUES (@date, - DAY(@date), - DATEPART(weekday, @date), - DATENAME(weekday, @date), - MONTH (@date)); - SET @date = DATEADD(day, 1, @date); - END \ No newline at end of file diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.503-20.504.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.503-20.504.sql new file mode 100644 index 000000000..d5968507b --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.503-20.504.sql @@ -0,0 +1,55 @@ +-- ================================================ +-- Template generated from Template Explorer using: +-- Create Procedure (New Menu).SQL +-- +-- Use the Specify Values for Template Parameters +-- command (Ctrl-Shift-M) to fill in the parameter +-- values below. +-- +-- This block of comments will not be included in +-- the definition of the procedure. +-- ================================================ +-- ============================================= +-- Author: jonesga@ohsu.edu +-- Create date: 2020-05-13 +-- Description: PRocedure to Block out Scheduling for Covid19 testing for 3:30 to 7 PM on Monday and Friday +-- ============================================= + +DROP PROCEDURE IF EXISTS extscheduler.extBlockOutEvening +GO +CREATE PROCEDURE extscheduler.extBlockOutEvening + -- Add the parameters for the stored procedure here + @Month INTEGER, @ResourceID INTEGER +AS +BEGIN + + INSERT INTO [extscheduler].[Events] + ([ResourceId] + ,[Name] + ,[StartDate] + ,[EndDate] + ,[UserId] + ,[Container] + ,[CreatedBy] + ,[Created] + ,[Quantity] + ,[Comments]) + + SELECT @ResourceID + ,'No Covid-19 Testing' + ,DateAdd(hh,1530,c.date) as StartDate + ,DateAdd(hh,19,c.date) as EndDate + ,1003 + ,'5C3C9FF8-6BCF-1038-930A-7D62F3A605B4' + ,1003 + ,GetDate() + ,1 + ,'Insert by ISE' + FROM [Labkey].[extscheduler].[dateParts] c + where c.dayofWeek in (2,6) and c.Month = @Month +--Days of Week start with Sunday + + + +END +GO diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql new file mode 100644 index 000000000..f4d0d0ca3 --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql @@ -0,0 +1,61 @@ +USE [Labkey] +GO +/****** Object: StoredProcedure [extscheduler].[extBlockOutMorning] Script Date: 5/13/2020 6:10:00 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ================================================ +-- Template generated from Template Explorer using: +-- Create Procedure (New Menu).SQL +-- +-- Use the Specify Values for Template Parameters +-- command (Ctrl-Shift-M) to fill in the parameter +-- values below. +-- +-- This block of comments will not be included in +-- the definition of the procedure. +-- ================================================ +-- ============================================= +-- Author: jonesga@ohsu.edu +-- Create date: 2020-05-13 +-- Description: PRocedure to Block out Scheduling for Covid19 testing for 7 to 8 on Monday and Friday +-- ============================================= +DROP PROCEDURE IF EXISTS [extscheduler].[extBlockOutMorning] +GO + +CREATE PROCEDURE [extscheduler].[extBlockOutMorning] + -- Add the parameters for the stored procedure here + @Month INTEGER, @ResourceID INTEGER +AS +BEGIN + + INSERT INTO [extscheduler].[Events] + ([ResourceId] + ,[Name] + ,[StartDate] + ,[EndDate] + ,[UserId] + ,[Container] + ,[CreatedBy] + ,[Created] + ,[Quantity] + ,[Comments]) + + SELECT @ResourceID + ,'No Covid-19 Testing' + ,DateAdd(hh,7,c.date) as StartDate + ,DateAdd(hh,8,c.date) as EndDate + ,1003 + ,'5C3C9FF8-6BCF-1038-930A-7D62F3A605B4' + ,1003 + ,GetDate() + ,1 + ,'Insert by ISE' + FROM [Labkey].[extscheduler].[dateParts] c + where c.dayofWeek in (2,6) and c.Month = @Month +--Days of Week start with Sunday + + + +END diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql new file mode 100644 index 000000000..2bae661c5 --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql @@ -0,0 +1,61 @@ +USE [Labkey] +GO +/****** Object: StoredProcedure [extscheduler].[extBlockOutDays] Script Date: 5/13/2020 6:12:06 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ================================================ +-- Template generated from Template Explorer using: +-- Create Procedure (New Menu).SQL +-- +-- Use the Specify Values for Template Parameters +-- command (Ctrl-Shift-M) to fill in the parameter +-- values below. +-- +-- This block of comments will not be included in +-- the definition of the procedure. +-- ================================================ +-- ============================================= +-- Author: jonesga@ohsu.edu +-- Create date: 2020-05-13 +-- Description: PRocedure to Block out Scheduling for Covid19 testing for all days except Monday and Friday +-- ============================================= +DROP PROCEDURE IF EXISTS [extscheduler].[extBlockOutDays] +GO + +CREATE PROCEDURE [extscheduler].[extBlockOutDays] + -- Add the parameters for the stored procedure here + @Month INTEGER, @ResourceID INTEGER +AS +BEGIN + + INSERT INTO [extscheduler].[Events] + ([ResourceId] + ,[Name] + ,[StartDate] + ,[EndDate] + ,[UserId] + ,[Container] + ,[CreatedBy] + ,[Created] + ,[Quantity] + ,[Comments]) + + SELECT @ResourceID + ,'No Covid-19 Testing' + ,DateAdd(hh,7,c.date) as StartDate + ,DateAdd(hh,19,c.date) as EndDate + ,1003 + ,'5C3C9FF8-6BCF-1038-930A-7D62F3A605B4' + ,1003 + ,GetDate() + ,1 + ,'Insert by ISE' + FROM [Labkey].[extscheduler].[dateParts] c + where c.dayofWeek in (1,3,4,5,7) and c.Month = @Month +--Days of Week start with Sunday + + + +END diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.601-20.602.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.601-20.602.sql new file mode 100644 index 000000000..338d08fb8 --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.601-20.602.sql @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2003-2005 Fred Hutchinson Cancer Research Center + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Created 2020-06-09 + * Created by jonesga + * Purpose - View joining Scheduler Resources, Events and the User Data + */ + + +DROP VIEW IF EXISTS extScheduler.vw_Covid19Research +GO + +CREATE VIEW extScheduler.vw_Covid19Research AS +SELECT extscheduler.Events.Id AS SChedulerID, extscheduler.Events.ResourceId, extscheduler.Resources.Name AS ResourceName, extscheduler.Events.Name, extscheduler.Events.StartDate, extscheduler.Events.UserId, + extscheduler.Events.CreatedBy, extscheduler.Events.Created, extscheduler.Events.Quantity, core.UsersData.IM AS EmployeeID +FROM extscheduler.Events LEFT OUTER JOIN + core.UsersData ON extscheduler.Events.UserId = core.UsersData.UserId LEFT OUTER JOIN + extscheduler.Resources ON extscheduler.Events.ResourceId = extscheduler.Resources.Id +WHERE (extscheduler.Events.ResourceId = 67) diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.602-20.603.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.602-20.603.sql new file mode 100644 index 000000000..8650874c6 --- /dev/null +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.602-20.603.sql @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2003-2005 Fred Hutchinson Cancer Research Center + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Created 2020-06-09 + * Created by jonesga + * Purpose - View joining Scheduler Resources, Events and the User Data + */ + +DROP VIEW IF EXISTS extScheduler.vw_Covid19DCMSchedule +GO + +CREATE VIEW extScheduler.vw_Covid19DCMSchedule AS +SELECT extscheduler.Events.Id AS SChedulerID, extscheduler.Events.ResourceId, extscheduler.Resources.Name AS ResourceName, extscheduler.Events.Name, extscheduler.Events.StartDate, extscheduler.Events.UserId, + extscheduler.Events.CreatedBy, extscheduler.Events.Created, extscheduler.Events.Quantity, core.UsersData.IM AS EmployeeID + FROM extscheduler.Events LEFT OUTER JOIN + core.UsersData ON extscheduler.Events.UserId = core.UsersData.UserId LEFT OUTER JOIN + extscheduler.Resources ON extscheduler.Events.ResourceId = extscheduler.Resources.Id + WHERE (extscheduler.Resources.Name LIKE 'DCM%') diff --git a/extscheduler/resources/web/extscheduler/App/view/EventForm.js b/extscheduler/resources/web/extscheduler/App/view/EventForm.js index 352f503d6..56e0ac4dd 100644 --- a/extscheduler/resources/web/extscheduler/App/view/EventForm.js +++ b/extscheduler/resources/web/extscheduler/App/view/EventForm.js @@ -93,17 +93,29 @@ Ext.define('App.view.EventForm', { } }, { - xtype : 'textfield', + xtype : 'textarea', + labelAlign: 'top', + width: 320, + height: 200, fieldLabel : 'Comments', name : 'Comments', reference : 'eventCommentsField', + style: 'margin-top: 20px;', allowBlank : true, hidden : this.eventFormColumns.indexOf('Comments') === -1, bind : { value : '{eventRecord.Comments}', readOnly : !this.editable } - }, + /* xtype: 'textarea', + labelAlign: 'top', + width: 500, + height: 200, + fieldLabel: 'Question/Comment', + name: 'comment', + style: 'margin-top: 20px;', + allowBlank: false + */ }, { xtype : 'fieldcontainer', layout : 'hbox', diff --git a/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java b/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java index 303f70bfb..4fc480344 100644 --- a/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java +++ b/extscheduler/src/org/labkey/extscheduler/ExtSchedulerModule.java @@ -1,3 +1,4 @@ +//update to add new data set package org.labkey.extscheduler; import org.jetbrains.annotations.NotNull; @@ -26,7 +27,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 20.503; + return 20.603; } @Override diff --git a/extscheduler/src/org/labkey/extscheduler/query/EventsTable.java b/extscheduler/src/org/labkey/extscheduler/query/EventsTable.java index df1fb2618..d4cdca344 100644 --- a/extscheduler/src/org/labkey/extscheduler/query/EventsTable.java +++ b/extscheduler/src/org/labkey/extscheduler/query/EventsTable.java @@ -39,7 +39,9 @@ public EventsTable(TableInfo table, ExtSchedulerQuerySchema schema, ContainerFil wrapAllColumns(true); SqlDialect dialect = getSchema().getSqlDialect(); - SQLFragment isOwnerSQL = new SQLFragment("CASE WHEN "+ ExprColumn.STR_TABLE_ALIAS +".UserId = ? OR " + ExprColumn.STR_TABLE_ALIAS +".CreatedBy = ? THEN " + +// Modified: 6-19-2020 R.Blasa Allow future events to be displayed + SQLFragment isOwnerSQL = new SQLFragment("CASE WHEN " + ExprColumn.STR_TABLE_ALIAS + ".StartDate >= {fn now()} AND (" + ExprColumn.STR_TABLE_ALIAS +".UserId = ? OR " + ExprColumn.STR_TABLE_ALIAS +".CreatedBy = ? ) THEN " + dialect.getBooleanTRUE() + " ELSE " + dialect.getBooleanFALSE() + " END"); isOwnerSQL.add(schema.getUser().getUserId()); isOwnerSQL.add(schema.getUser().getUserId()); @@ -51,12 +53,10 @@ public EventsTable(TableInfo table, ExtSchedulerQuerySchema schema, ContainerFil // disable bulk import for all users setImportURL(AbstractTableInfo.LINK_DISABLER); - // only allow admins to see insert new button and edit links - if (!getContainer().hasPermission(schema.getUser(), AdminPermission.class)) - { - setInsertURL(AbstractTableInfo.LINK_DISABLER); - setUpdateURL(AbstractTableInfo.LINK_DISABLER); - } + +// Added: 6-15-2020 R.Blasa allowed delete option +// setDeleteURL(AbstractTableInfo.LINK_DISABLER); + } @Override diff --git a/onprc_billing/resources/etls/ogaSynch2019.xml b/onprc_billing/resources/etls/ogaSynch2019.xml deleted file mode 100644 index daa35a212..000000000 --- a/onprc_billing/resources/etls/ogaSynch2019.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - OGASync2018 - - Copies OGA Data from external source to PRIME for PRocessing - - - - - - Import to OGA Sync in Prime - - - - - - - - - - - - - - - diff --git a/onprc_billing/resources/etls/ogaSynchDataOnly.xml b/onprc_billing/resources/etls/ogaSynchDataOnly.xml deleted file mode 100644 index c6602df1a..000000000 --- a/onprc_billing/resources/etls/ogaSynchDataOnly.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - OGASyncDataOnly - - Copies OGA Data from external source to PRIME for PRocessing - - - - - - Import to OGA Sync in Prime - - - - - - - - - - - - - - diff --git a/onprc_billing/resources/etls/ogaSynchOnlyUAT.xml b/onprc_billing/resources/etls/ogaSynchOnlyUAT.xml deleted file mode 100644 index 59b93dfcf..000000000 --- a/onprc_billing/resources/etls/ogaSynchOnlyUAT.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - OGASyncDataOnly - - Copies OGA Data from external source to PRIME for PRocessing - - - - - - Import to OGA Sync in Prime - No additional Actions - - - - - - - - - - - - - - diff --git a/onprc_billing/resources/queries/onprc_billing/ActiveAlias_2020.query.xml b/onprc_billing/resources/queries/onprc_billing/ActiveAlias_2020.query.xml new file mode 100644 index 000000000..04f7700c8 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/ActiveAlias_2020.query.xml @@ -0,0 +1,78 @@ + + + +
    + Active Aliases ONPRC + org.labkey.ehr.table.DefaultEHRCustomizer + + + + + + OGA Award Nummber + + + + + + + + + MM-dd-yyyy + + + MM-dd-yyyy + + + + + onprc_billing + investigators + employeeID + InvestigatorID + + + + + + onprc_billing + fiscalAuthorities + employeeid + rowID + + + + 0.00 + + + + + MM-dd-yyyy + + + + + + + +
    + sorts> + + + + + + + + + \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/Activealias_2020.sql b/onprc_billing/resources/queries/onprc_billing/Activealias_2020.sql new file mode 100644 index 000000000..6558c1da5 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/Activealias_2020.sql @@ -0,0 +1,39 @@ +SELECT a.alias, + a.category, + a.aliasEnabled, + a.projectNumber, + a.grantNumber as OGAAwardNumber, + a.agencyAwardNumber, + a.investigatorId, + a.investigatorName, + a.fiscalAuthority, + a.fiscalAuthorityName, + a.budgetStartDate, + a.budgetEndDate, + a.faRate, + a.faSchedule, + a.projectTitle, + a.projectDescription, + a.projectStatus, + a.aliasType, + a.container, + a.dateDisabled, + a.Comments, + a.PPQNumber, + a.PPQDate, + a.ApplicationTypeDescription, + a.AwardStatus, + a.AwardID, + a.ApplicationType, + a.ProjectID, + a.ActivityType, + a.AwardNumber, + a.AwardSuffix, + a.ADFMEmpNum, + a.ADFMFullName, + a.ActivityTypeDescription, + a.FUndingSourceNumber, + a.FUndingSourceName, + a.Org +FROM aliases a +where aliasEnabled = 'y' \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/aliases/.qview.xml b/onprc_billing/resources/queries/onprc_billing/aliases/.qview.xml index b3b117007..4b9701c0a 100644 --- a/onprc_billing/resources/queries/onprc_billing/aliases/.qview.xml +++ b/onprc_billing/resources/queries/onprc_billing/aliases/.qview.xml @@ -5,8 +5,11 @@ + + + @@ -14,8 +17,15 @@ + - + + + + + + +
    diff --git a/onprc_billing/resources/queries/onprc_billing/oga_AliasCleanup2020.sql b/onprc_billing/resources/queries/onprc_billing/oga_AliasCleanup2020.sql new file mode 100644 index 000000000..1ef6a8ed3 --- /dev/null +++ b/onprc_billing/resources/queries/onprc_billing/oga_AliasCleanup2020.sql @@ -0,0 +1,80 @@ +USE [Labkey] +GO +/****** Object: StoredProcedure [onprc_billing].[oga_AliasCleanupNew] Script Date: 1/29/2020 7:13:37 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +CREATE PROCEDURE [onprc_billing].[oga_AliasCleanup] + + AS + BEGIN + +--This update will be used to enter date disabled for all aliases used in Invoiced Items +--This update will be used to enter date disabled for all aliases used in Invoiced Items +Update onprc_billing.aliases + Set COMMENTS = 'Found In PRoject Account History',dateDisabled = GetDate(), aliasEnabled = 'n' +Where alias in (Select Distinct Alias + + +from onprc_billing.aliases a left outer join onprc_billing.projectAccountHistory p + on a.alias = p.account + where p.account is not null and p.enddate < getDate() + and a.category != 'OHSU GL' ) --and a.projectStatus != 'Active') + + +--This update will be used to enter date disabled for all aliases used in Invoiced Items +Update onprc_billing.aliases + Set COMMENTS = 'Found In INvoiced ITem',dateDisabled = GetDate(), aliasEnabled = 'n' +Where alias in (Select Distinct Alias + + +from onprc_billing.aliases a left outer join onprc_billing.invoicedItems i + on a.alias = i.debitedaccount + where i.debitedaccount is not null + and a.category != 'OHSU GL')--and a.projectStatus != 'Active') + + +/* + + --Handles active non OGA Aliases + Update a + Set a.projectStatus = 'Active',a.comments = 'In Use - Non ONPRC Alias', a.category = 'OHSU GL' + +--Select a.Alias,p.account -- update the category to + from onprc_billing.aliases a join onprc_billing.projectAccountHistory p on p.account = a.alias + where p.enddate > = GetDate() and a.alias Not Like '9%' + +--handle inactive GL Aliases in the Dataset + Update gl + set gl.projectStatus = 'Non Active GL', gl.aliasEnabled = 'n', gl.datedisabled = GetDate(), gl.comments = 'GL Alias Not Active entered Previously' + +--Select gl.* + from onprc_billing.aliases gl left outer join onprc_billing.projectAccountHistory p on p.account = gl.alias + where gl.alias not like '9%' and (gl.comments != 'In Use - Non ONPRC Alias' or gl.comments is null) + +--Handles Expired Aliases by setting Date Disabled + Update a1 + Set a1.dateDisabled = GetDate(), comments = 'Expired Alias' +--select a1.alias,a1.budgetEndDate + from onprc_billing.aliases a1 + where a1.budgetEndDate <=GetDate() + + Update a4 + set dateDisabled = GetDate(), comments = 'Grant Closed', projectStatus = 'Grant Closed' +--Select a4.alias,s.[PROJECT STATUS],a4.projectStatus + from onprc_billing.aliases a4 left Outer join onprc_billing.ogaSynch s on Cast(a4.alias as varchar(50)) = Cast(s.[alias] as VarChar(50)) + where a4.dateDisabled is null and a4.projectstatus in ('Archived','Closed','IM PURGEd') + +--Update the existing data to add PPQ, ORG PPQ Date to Existing Aliases + + Update a10 + Set organization = s.ORG, a10.PPQCode = s.[PPQ CODE], a10.PPQDate = s.[PPQ DATE] + + + from onprc_billing.aliases a10 left Outer join onprc_billing.ogaSynch s on Cast(a10.alias as varchar(50)) = Cast(s.[alias] as VarChar(50)) + where a10.Organization is null +*/ + + END \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/procedureFeeDefinition.js b/onprc_billing/resources/queries/onprc_billing/procedureFeeDefinition.js index 24f61da7d..68f8a9792 100644 --- a/onprc_billing/resources/queries/onprc_billing/procedureFeeDefinition.js +++ b/onprc_billing/resources/queries/onprc_billing/procedureFeeDefinition.js @@ -16,8 +16,8 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even if (row.assistingstaff && row.procedureid && !onprcTriggerHelper.requiresAssistingStaff(row.procedureid)){ EHR.Server.Utils.addError(scriptErrors, 'assistingstaff', 'Only surgeries support assisting staff.', 'ERROR'); } - - if (row.chargetype != 'Research Staff' && row.assistingstaff){ + //Modified: 6-9-2020 R. Blasa to allow to process Infectious Disease Resource as Charge unit + if (row.chargetype != 'Research Staff' && row.assistingstaff && row.assistingstaff != 'DCM: Surgery Services'){ EHR.Server.Utils.addError(scriptErrors, 'assistingstaff', 'This field will be ignored unless Research Staff is selected, and should be blank.', 'ERROR'); } }); diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.104-20.105.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.104-20.105.sql new file mode 100644 index 000000000..684ad4a48 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.104-20.105.sql @@ -0,0 +1,39 @@ +-- Adding additional Fields for Alias insert from OGA Synch +--Rerunning and it does not appear in Build +--2020-03-4 Revision to add this to UAT +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ApplicationType]; +ALTER TABLE onprc_billing.aliases ADD [ApplicationType] VarChar(255) Null; + +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ApplicationTypeDescription]; +ALTER TABLE onprc_billing.aliases ADD [ApplicationTypeDescription] VarChar(255) Null; + +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardStatus]; +ALTER TABLE onprc_billing.aliases ADD [AwardStatus] VARCHAR(100) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardID]; +ALTER TABLE onprc_billing.aliases ADD [AwardID] VARCHAR(100) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ApplicationType]; +ALTER TABLE onprc_billing.aliases ADD [ApplicationType] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ProjectID]; +ALTER TABLE onprc_billing.aliases ADD [ProjectID] VARCHAR(100) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ActivityType]; +ALTER TABLE onprc_billing.aliases ADD [ActivityType] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardNumber]; +ALTER TABLE onprc_billing.aliases ADD [AwardNumber] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardSuffix]; +ALTER TABLE onprc_billing.aliases ADD [AwardSuffix] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [Org]; +ALTER TABLE onprc_billing.aliases ADD [Org] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ADFMEmpNum]; +ALTER TABLE onprc_billing.aliases ADD [ADFMEmpNum] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ADFMFullName]; +ALTER TABLE onprc_billing.aliases ADD [ADFMFullName] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ActivityTypeDescription]; +ALTER TABLE onprc_billing.aliases ADD [ActivityTypeDescription] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [FundingSourceNumber]; +ALTER TABLE onprc_billing.aliases ADD [FUndingSourceNumber] VARCHAR(255) NUll +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [FundingSourceName]; +ALTER TABLE onprc_billing.aliases ADD [FUndingSourceName] VARCHAR(255) NUll +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [Org]; +ALTER TABLE onprc_billing.aliases ADD [Org] VARCHAR(255) NUll + +--Adding additional fields to OGA Synch diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.508-20.509.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.508-20.509.sql new file mode 100644 index 000000000..684ad4a48 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.508-20.509.sql @@ -0,0 +1,39 @@ +-- Adding additional Fields for Alias insert from OGA Synch +--Rerunning and it does not appear in Build +--2020-03-4 Revision to add this to UAT +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ApplicationType]; +ALTER TABLE onprc_billing.aliases ADD [ApplicationType] VarChar(255) Null; + +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ApplicationTypeDescription]; +ALTER TABLE onprc_billing.aliases ADD [ApplicationTypeDescription] VarChar(255) Null; + +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardStatus]; +ALTER TABLE onprc_billing.aliases ADD [AwardStatus] VARCHAR(100) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardID]; +ALTER TABLE onprc_billing.aliases ADD [AwardID] VARCHAR(100) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ApplicationType]; +ALTER TABLE onprc_billing.aliases ADD [ApplicationType] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ProjectID]; +ALTER TABLE onprc_billing.aliases ADD [ProjectID] VARCHAR(100) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ActivityType]; +ALTER TABLE onprc_billing.aliases ADD [ActivityType] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardNumber]; +ALTER TABLE onprc_billing.aliases ADD [AwardNumber] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [AwardSuffix]; +ALTER TABLE onprc_billing.aliases ADD [AwardSuffix] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [Org]; +ALTER TABLE onprc_billing.aliases ADD [Org] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ADFMEmpNum]; +ALTER TABLE onprc_billing.aliases ADD [ADFMEmpNum] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ADFMFullName]; +ALTER TABLE onprc_billing.aliases ADD [ADFMFullName] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [ActivityTypeDescription]; +ALTER TABLE onprc_billing.aliases ADD [ActivityTypeDescription] VARCHAR(255) NUll; +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [FundingSourceNumber]; +ALTER TABLE onprc_billing.aliases ADD [FUndingSourceNumber] VARCHAR(255) NUll +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [FundingSourceName]; +ALTER TABLE onprc_billing.aliases ADD [FUndingSourceName] VARCHAR(255) NUll +ALTER TABLE onprc_billing.aliases DROP COLUMN IF EXISTS [Org]; +ALTER TABLE onprc_billing.aliases ADD [Org] VARCHAR(255) NUll + +--Adding additional fields to OGA Synch diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql new file mode 100644 index 000000000..f734d5d51 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql @@ -0,0 +1,21 @@ + +/****** Object: StoredProcedure [onprc_billing].[OGA_RemoveRecords] + cREATED 2020-05-18 + cREATED BY JONESGA + Purpose: Resets the Alias Dataset for Insert from OGA, Keeping GL Accounts + + Script Date: 5/18/2020 10:33:15 AM ******/ +DROP PROCEDURE IF EXISTS [onprc_billing].[OGA_RemoveRecords] +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE PROCEDURE [onprc_billing].[OGA_RemoveRecords] + AS + BEGIN + + Delete from onprc_billing.aliases + where category != 'OHSU GL' + + + + END \ No newline at end of file diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql new file mode 100644 index 000000000..6098e39e9 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql @@ -0,0 +1,86 @@ + +/****** Object: StoredProcedure [onprc_billing].[oga_InsertRecords] Script Date: 5/18/2020 10:35:50 AM ******/ +SET ANSI_NULLS ON +GO +DROP PROCEDURE IF EXISTS [onprc_billing].[oga_InsertRecords] +GO +SET QUOTED_IDENTIFIER ON +GO +CREATE PROCEDURE [onprc_billing].[oga_InsertRecords] + + AS + BEGIN + + INSERT INTO [onprc_billing].[aliases] + ([alias] + ,[aliasEnabled] + ,[projectNumber] + ,[grantNumber] + ,[agencyAwardNumber] + ,[investigatorId] + ,[investigatorName] + ,[fiscalAuthority] + ,[container] + ,[createdBy] + ,[created] + ,[category] + ,[faRate] + ,[faSchedule] + ,[budgetStartDate] + ,[budgetEndDate] + ,[projectTitle] + ,[projectDescription] + ,[projectStatus] + ,[aliasType] + ,[COMMENTS] + ,[PPQNumber] + ,[PPQDate] + ,[AwardStatus] + ,[AwardID] + ,[ApplicationType] + ,[ProjectID] + ,[ActivityType] + ,[AwardNumber] + ,[AwardSuffix] + ,[ADFMEmpNum] + ,[ADFMFullName] + ,[Org] + ) + SELECT + [Alias] + ,[ALIAS ENABLED FLAG_MVIndicator] + ,[OGA PROJECT NUMBER] + ,[OGA AWARD NUMBER] + ,[AGENCY AWARD NUMBER] + ,[PI EMP NUM] + ,[PI FULL NAME] + ,[PDFM EMP NUM] + ,'0F8BB08E-E4BF-102F-B89B-5107380A5B61' + ,1003 + ,GetDate() + ,'OGA' + ,[BURDEN RATE] + ,[BURDEN SCHEDULE] + ,[CURRENT BUDGET START DATE] + ,[CURRENT BUDGET END DATE] + ,[PROJECT TITLE] + ,[PROJECT DESCRIPTION] + ,[PROJECT STATUS] + ,[ACTIVITY TYPE] + ,'ENTERED BY ISE' + ,[PPQ CODE] + ,[PPQ DATE] + ,[AWARD STATUS] + ,[AWARD ID] + ,[APPLICATION TYPE] + ,[PROJECT ID] + ,[OGA AWARD TYPE] + ,[AWARD NUMBER] + ,[AWARD SUFFIX] + ,[ADFM EMP NUM] + ,[ADFM FULL NAME] + ,[ORG] + From [onprc_billing].[ogasynch] + END + + diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql new file mode 100644 index 000000000..1b90268e4 --- /dev/null +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql @@ -0,0 +1,105 @@ +USE [Labkey] +GO +/****** Object: StoredProcedure [onprc_billing].[oga_InsertRecords] Script Date: 5/21/2020 5:43:28 AM ******/ +/*****Update 2020-05-21 to handle Investigator and FA Ids in Prime*******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +ALTER PROCEDURE [onprc_billing].[oga_InsertRecords] + + AS + BEGIN + + INSERT INTO [onprc_billing].[aliases] + ([alias] + ,[aliasEnabled] + ,[projectNumber] + ,[grantNumber] + ,[agencyAwardNumber] + ,[investigatorId] + ,[investigatorName] + ,[fiscalAuthority] + ,[container] + ,[createdBy] + ,[created] + ,[category] + ,[faRate] + ,[faSchedule] + ,[budgetStartDate] + ,[budgetEndDate] + ,[projectTitle] + ,[projectDescription] + ,[projectStatus] + ,[aliasType] + ,[COMMENTS] + ,[PPQNumber] + ,[PPQDate] + ,[AwardStatus] + ,[AwardID] + ,[ApplicationType] + ,[ProjectID] + ,[ActivityType] + ,[AwardNumber] + ,[AwardSuffix] + ,[ADFMEmpNum] + ,[ADFMFullName] + ,[Org] + ) + SELECT + [Alias] + ,Case + when [ALIAS ENABLED FLAG] = 0 then 'n' + when [ALIAS ENABLED FLAG] = 1 then 'y' + End as AliasEndabled + + --,[ALIAS ENABLED FLAG] + ,[OGA PROJECT NUMBER] + ,[OGA AWARD NUMBER] + ,[AGENCY AWARD NUMBER] + ,Case + When (Select rowID from [onprc_ehr].[investigators] where [PI EMP NUM] = employeeID and datedisabled is null) is not null + Then (Select rowID from [onprc_ehr].[investigators] where [PI EMP NUM] = employeeID and datedisabled is null) + Else Null + End as InvestigatorID + -- ,[PI EMP NUM] + -- ,(Select rowID from [onprc_ehr].[investigators] where [PI EMP NUM] = employeeID and datedisabled is null) as PILastName + -- [PI EMP NUM] + ,[PI FULL NAME] + ,(Select rowid from [onprc_billing].[fiscalAuthorities] where [PDFM EMP NUM] = employeeID and active = 1) as fiscalAuthority + ,'0F8BB08E-E4BF-102F-B89B-5107380A5B61' + ,1003 + ,GetDate() + ,'OGA' + ,[BURDEN RATE] + ,[BURDEN SCHEDULE] + ,[CURRENT BUDGET START DATE] + ,[CURRENT BUDGET END DATE] + ,[PROJECT TITLE] + ,[PROJECT DESCRIPTION] + ,[PROJECT STATUS] + ,[ACTIVITY TYPE] + ,'ENTERED BY ISE' + ,[PPQ CODE] + ,[PPQ DATE] + ,[AWARD STATUS] + ,[AWARD ID] + ,[APPLICATION TYPE] + ,[PROJECT ID] + ,[OGA AWARD TYPE] + ,[AWARD NUMBER] + ,[AWARD SUFFIX] + ,[ADFM EMP NUM] + ,[ADFM FULL NAME] + ,[ORG] + From [onprc_billing].[ogasynch] + + Update [Labkey].[onprc_billing].[aliases] + Set aliasEnabled = 'n' + --where AliasEnabled is null + --Select * from [Labkey].[onprc_billing].[aliases] + where ((budgetEndDate < GetDate() or budgetEndDate is null) or category != 'OHSU GL') + + END + + diff --git a/onprc_billing/resources/schemas/onprc_billing.xml b/onprc_billing/resources/schemas/onprc_billing.xml index 7bc72c47a..41df2bf2b 100644 --- a/onprc_billing/resources/schemas/onprc_billing.xml +++ b/onprc_billing/resources/schemas/onprc_billing.xml @@ -1151,9 +1151,11 @@
    OGA Grant Number + Agency Award Number + Investigator @@ -1207,6 +1209,11 @@ + + + + + diff --git a/onprc_ehr/resources/etls/extSchedulerCovid19.xml b/onprc_ehr/resources/etls/extSchedulerCovid19.xml new file mode 100644 index 000000000..5caa17eee --- /dev/null +++ b/onprc_ehr/resources/etls/extSchedulerCovid19.xml @@ -0,0 +1,41 @@ + + + + + Covid19Scheduler + + This ETL Runs a series of Stored Procedures to Block out Section of Scheduler + + + + + + Runs Stored Procedure to Block out All Days Except Monday and Friday + + + + + + Runs a stored procedure to BLock out 7 to 8 AM MOnday and Friday. + + + + + + Runs a stored procedure to BLock out 3:30 to 7 PM MOnday and Friday. + + + + + + + + + + + + diff --git a/onprc_ehr/resources/etls/ogaAliasCleanup2020.xml b/onprc_ehr/resources/etls/ogaAliasCleanup2020.xml new file mode 100644 index 000000000..efccb1e45 --- /dev/null +++ b/onprc_ehr/resources/etls/ogaAliasCleanup2020.xml @@ -0,0 +1,25 @@ + + + + + ogaAliasCleanUp2020 + + Code to enddate or remove Aliases not Assocatied with ONPRC + + + + + Code to enddate or remove Aliases not Assocatied with ONPRC. + + + + + + + + + + + diff --git a/onprc_billing/resources/etls/ogaSynch2020.xml b/onprc_ehr/resources/etls/ogaSynch2020.xml similarity index 100% rename from onprc_billing/resources/etls/ogaSynch2020.xml rename to onprc_ehr/resources/etls/ogaSynch2020.xml diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index 2c89bbea0..c50d79184 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -237,8 +237,8 @@ exports.init = function(EHR){ { EHR.Server.Utils.addError(scriptErrors, 'chargetype', 'If choosing Research Staff, you must enter the assisting staff.', 'WARN'); } - - if (row.chargetype != 'Research Staff' && row.assistingstaff) + //Modified: 6-9-2020 R. Blasa to allow to process Infectious Disease Resource as Charge unit + if (row.chargetype != 'Research Staff' && row.assistingstaff && row.assistingstaff != 'DCM: Surgery Services') { EHR.Server.Utils.addError(scriptErrors, 'assistingstaff', 'This field will be ignored unless Research Staff is selected, and should be blank.', 'WARN'); } diff --git a/onprc_ehr/resources/views/Covid19Scheduler.html b/onprc_ehr/resources/views/Covid19Scheduler.html new file mode 100644 index 000000000..d7fb324f4 --- /dev/null +++ b/onprc_ehr/resources/views/Covid19Scheduler.html @@ -0,0 +1,50 @@ + + + + + ONPRC Covid 19 Test SCheduler + + + + + + --> + + } + + +

    Covid 19 Testing Scheduler

    +
    + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/Covid19Scheduler.webpart.xml b/onprc_ehr/resources/views/Covid19Scheduler.webpart.xml new file mode 100644 index 000000000..9ed3fb731 --- /dev/null +++ b/onprc_ehr/resources/views/Covid19Scheduler.webpart.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/views/Covie19Scheduler.view.xml b/onprc_ehr/resources/views/Covie19Scheduler.view.xml new file mode 100644 index 000000000..c1c27eb87 --- /dev/null +++ b/onprc_ehr/resources/views/Covie19Scheduler.view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index da5a1a85f..04236193c 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -1051,7 +1051,6 @@ protected void bsuNotesAlert(final Container c, User u, final StringBuilder msg) } /** -<<<<<<< .mine * Kollil, 10/24/2019 : PMIC scheduler alert notifications Daily & Weekly */ protected void pmicSchedulerAlert(final Container c, User u, final StringBuilder msg) @@ -1182,139 +1181,6 @@ public void exec(ResultSet object) throws SQLException { } /** -||||||| .r64573 -======= - * Kollil, 10/24/2019 : PMIC scheduler alert notifications Daily & Weekly - */ -// protected void pmicSchedulerAlert(final Container c, User u, final StringBuilder msg) -// { -// //PMIC container: 783D2EA5-C6AC-1036-A33C-BD25D0574070 -// if (QueryService.get().getUserSchema(u, c, "extscheduler") == null) { -// msg.append("Warning: The extscheduler schema has not been enabled in this folder, so the alert cannot run!


    "); -// return; -// } -// //Daily events query -// TableInfo ti = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler"); -// ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); -// TableSelector ts = new TableSelector(ti, null, null); -// long count = ts.getRowCount(); -// -// //Weekly events query -// TableInfo ti1 = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler_Weekly"); -// ((ContainerFilterable) ti1).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); -// TableSelector ts1 = new TableSelector(ti1, null, null); -// long count1 = ts1.getRowCount(); -// -// if (count > 0) {//Daily events count -// msg.append("There are " + count + " PMIC events scheduled for today:"); -// msg.append("

    Click here to view them

    \n"); -// msg.append("
    "); -// } -// if (count1 > 0) {//Weekly events count -// msg.append("There are " + count1 + " PMIC events scheduled this week:"); -// msg.append("

    Click here to view them

    \n"); -// msg.append("
    "); -// } -// //Display the daily report in the email -// if (count > 0) { -// Set columns = new HashSet<>(); -// columns.add(FieldKey.fromString("resourceid")); -// columns.add(FieldKey.fromString("startdate")); -// columns.add(FieldKey.fromString("enddate")); -// columns.add(FieldKey.fromString("name")); -// columns.add(FieldKey.fromString("alias")); -// columns.add(FieldKey.fromString("quantity")); -// columns.add(FieldKey.fromString("comments")); -// columns.add(FieldKey.fromString("color")); -// columns.add(FieldKey.fromString("room")); -// columns.add(FieldKey.fromString("bldg")); -// -// final Map colMap = QueryService.get().getColumns(ti, columns); -// TableSelector ts2 = new TableSelector(ti, colMap.values(), null, null); -// count = ts2.getRowCount(); -// -// if (count == 0) { -// msg.append("There are no scheduled PMIC events"); -// } -// else { -// msg.append("
    Daily PMIC events:

    \n"); -// msg.append("
    "); -// msg.append(""); -// msg.append(""); -// -// ts2.forEach(new Selector.ForEachBlock() { -// @Override -// public void exec(ResultSet object) throws SQLException { -// Results rs = new ResultsImpl(object, colMap); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// } -// }); -// msg.append("
    Resource Id Start Date End Date Name Alias Quantity Comments Color Room Bldg
    " + rs.getString("resourceid") + "" + rs.getString("startdate") + "" + rs.getString("enddate") + "" + rs.getString("name") + "" + rs.getString("alias") + "" + rs.getString("quantity") + "" + rs.getString("comments") + "" + rs.getString("color") + "" + rs.getString("room") + "" + rs.getString("bldg") + "
    "); -// } -// //Display the weekly report in the email -// if (count1 > 0) { -// Set columns1 = new HashSet<>(); -// columns1.add(FieldKey.fromString("resourceid")); -// columns1.add(FieldKey.fromString("startdate")); -// columns1.add(FieldKey.fromString("enddate")); -// columns1.add(FieldKey.fromString("name")); -// columns1.add(FieldKey.fromString("alias")); -// columns1.add(FieldKey.fromString("quantity")); -// columns1.add(FieldKey.fromString("comments")); -// columns1.add(FieldKey.fromString("color")); -// columns1.add(FieldKey.fromString("room")); -// columns1.add(FieldKey.fromString("bldg")); -// -// final Map colMap1 = QueryService.get().getColumns(ti1, columns1); -// TableSelector ts3 = new TableSelector(ti1, colMap1.values(), null, null); -// count1 = ts3.getRowCount(); -// -// if (count1 == 0) { -// msg.append("There are no scheduled PMIC events"); -// } -// else { -// msg.append("

    Weekly PMIC events:

    \n"); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// -// ts3.forEach(new Selector.ForEachBlock() { -// @Override -// public void exec(ResultSet object) throws SQLException { -// Results rs1 = new ResultsImpl(object, colMap1); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// msg.append(""); -// } -// }); -// msg.append("
    Resource Id Start Date End Date Name Alias Quantity Comments Color Room Bldg
    " + rs1.getString("resourceid") + "" + rs1.getString("startdate") + "" + rs1.getString("enddate") + "" + rs1.getString("name") + "" + rs1.getString("alias") + "" + rs1.getString("quantity") + "" + rs1.getString("comments") + "" + rs1.getString("color") + "" + rs1.getString("room") + "" + rs1.getString("bldg") + "
    "); -// } -// } -// } -// } - - /** ->>>>>>> .r65353 * we find protocols over the animal limit */ protected void protocolsOverLimit(final Container c, User u, final StringBuilder msg) @@ -2132,7 +1998,7 @@ else if (count > 65) protected void infantsNotWithMother(final Container c, User u, final StringBuilder msg) { SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Id/age/ageInDays"), 180, CompareType.LTE); - //Added by Kolli1, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates + //Added by Kollil, 6/11. Excluding the Guinea pigs & Rabbits and showing only primates //filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG;RABBIT", CompareType.CONTAINS_NONE_OF); filter.addCondition(FieldKey.fromString("Id/demographics/species/common"), "GUINEA PIG", CompareType.NEQ); filter.addCondition(FieldKey.fromString("Id/demographics/calculated_status"), "Alive", CompareType.EQUAL); @@ -2144,11 +2010,13 @@ protected void infantsNotWithMother(final Container c, User u, final StringBuild ASB RM 185 COL RM 4 */ + //Added ASB 239 to this list on 5/14/2020 byt kolli //filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 191", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 213", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 236", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 240", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 185", CompareType.NEQ_OR_NULL); + filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "ASB RM 239", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("Id/curLocation/room"), "COL RM 4", CompareType.NEQ_OR_NULL); filter.addCondition(FieldKey.fromString("withMother"), 0, CompareType.EQUAL); @@ -2164,7 +2032,7 @@ protected void infantsNotWithMother(final Container c, User u, final StringBuild long count = ts.getRowCount(); if (count > 0) { - msg.append("NOTE: There are " + count + " animals under 180 days old not housed with their dam or foster dam, excluding animals in ASB RM 213, ASB RM 236, ASB RM 240, ASB RM 185 & COL RM 4

    "); + msg.append("NOTE: There are " + count + " animals under 180 days old not housed with their dam or foster dam, excluding animals in ASB RM 213, ASB RM 236, ASB RM 240, ASB RM 185, ASB RM 239 & COL RM 4

    "); ts.forEach(new Selector.ForEachBlock() { @Override From ed6604bf8ec2e546bcccc02cbcc87b19b4ff9f1f Mon Sep 17 00:00:00 2001 From: Binal Date: Thu, 8 Oct 2020 00:20:25 -0700 Subject: [PATCH 16/49] Merge from onprc19.1 r.65678 to 65757 --- .../sqlserver/extscheduler-20.504-20.505.sql | 12 +- .../sqlserver/extscheduler-20.505-20.506.sql | 14 +- .../sqlserver/onprc_billing-20.410-20.411.sql | 5 - .../sqlserver/onprc_billing-20.511-20.512.sql | 2 - .../sqlserver/onprc_billing-20.512-20.513.sql | 5 +- .../sqlserver/onprc_billing-20.514-20.515.sql | 7 +- .../onprc_billing/ONPRC_BillingModule.java | 2 +- .../queries/study/Histology.query.xml | 9 +- .../queries/study/Pairings.query.xml | 8 +- .../queries/study/Tissue Measurements.js | 7 - .../queries/study/Treatment Orders.query.xml | 181 ------------------ .../.qview.xml | 0 .../Behavior Remarks.qview.xml | 0 .../CEG_Plan.qview.xml | 0 .../SOAP Note.qview.xml | 0 .../study/{iStat => grossFindings}/.qview.xml | 0 .../queries/study/pairingEvents.query.xml | 3 - .../queries/study/pairingSummary.query.xml | 3 - .../study/pairingSummaryComments.query.xml | 3 - .../.qview.xml | 0 .../.qview.xml | 0 .../queries/study/{TB Tests.js => tb.js} | 0 .../{TB Tests.query.xml => tb.query.xml} | 0 ...17.706.sql => onprc_ehr-20.414-20.415.sql} | 0 .../resources/views/Covid19Scheduler.html | 2 +- onprc_ehr/resources/views/animalHistory.html | 1 + onprc_ehr/resources/views/onprcMenu.html | 16 ++ .../resources/views/quickSearchonprc.html | 25 ++- .../sources/TreatmentOrdersClientStore.js | 81 ++++++++ .../form/field/onprc_SlaCensusConfig.js | 50 ++++- .../onprc_ehr/model/sources/SurgeryBlood.js | 8 +- .../web/onprc_ehr/panel/EnterDataPanel.js | 84 +++++--- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 2 +- .../dataentry/TreatmentOrdersFormSection.java | 5 + .../query/ONPRC_EHRTriggerHelper.java | 8 +- .../onprc_ehr/table/ONPRC_EHRCustomizer.java | 1 - .../web/sla/window/AddCensusWindow.js | 31 +-- 37 files changed, 273 insertions(+), 302 deletions(-) delete mode 100644 onprc_ehr/resources/queries/study/Tissue Measurements.js delete mode 100644 onprc_ehr/resources/queries/study/Treatment Orders.query.xml rename onprc_ehr/resources/queries/study/{Clinical Remarks => clinremarks}/.qview.xml (100%) rename onprc_ehr/resources/queries/study/{Clinical Remarks => clinremarks}/Behavior Remarks.qview.xml (100%) rename onprc_ehr/resources/queries/study/{Clinical Remarks => clinremarks}/CEG_Plan.qview.xml (100%) rename onprc_ehr/resources/queries/study/{Clinical Remarks => clinremarks}/SOAP Note.qview.xml (100%) rename onprc_ehr/resources/queries/study/{iStat => grossFindings}/.qview.xml (100%) rename onprc_ehr/resources/queries/study/{Parasitology Results => parasitologyResults}/.qview.xml (100%) rename onprc_ehr/resources/queries/study/{Pregnancy Confirmations => pregnancyConfirmations}/.qview.xml (100%) rename onprc_ehr/resources/queries/study/{TB Tests.js => tb.js} (100%) rename onprc_ehr/resources/queries/study/{TB Tests.query.xml => tb.query.xml} (100%) rename onprc_ehr/resources/schemas/dbscripts/sqlserver/{onprc_ehr-17.705-17.706.sql => onprc_ehr-20.414-20.415.sql} (100%) create mode 100644 onprc_ehr/resources/web/onprc_ehr/data/sources/TreatmentOrdersClientStore.js diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql index f4d0d0ca3..8e6c6349d 100644 --- a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.504-20.505.sql @@ -1,10 +1,10 @@ -USE [Labkey] -GO +-- USE [Labkey] +-- GO /****** Object: StoredProcedure [extscheduler].[extBlockOutMorning] Script Date: 5/13/2020 6:10:00 AM ******/ -SET ANSI_NULLS ON -GO -SET QUOTED_IDENTIFIER ON -GO +-- SET ANSI_NULLS ON +-- GO +-- SET QUOTED_IDENTIFIER ON +-- GO -- ================================================ -- Template generated from Template Explorer using: -- Create Procedure (New Menu).SQL diff --git a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql index 2bae661c5..5a99c96f9 100644 --- a/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql +++ b/extscheduler/resources/schemas/dbscripts/sqlserver/extscheduler-20.505-20.506.sql @@ -1,10 +1,10 @@ -USE [Labkey] -GO -/****** Object: StoredProcedure [extscheduler].[extBlockOutDays] Script Date: 5/13/2020 6:12:06 AM ******/ -SET ANSI_NULLS ON -GO -SET QUOTED_IDENTIFIER ON -GO +-- USE [Labkey] +-- GO +-- /****** Object: StoredProcedure [extscheduler].[extBlockOutDays] Script Date: 5/13/2020 6:12:06 AM ******/ +-- SET ANSI_NULLS ON +-- GO +-- SET QUOTED_IDENTIFIER ON +-- GO -- ================================================ -- Template generated from Template Explorer using: -- Create Procedure (New Menu).SQL diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql index 31248e562..feff5121f 100644 --- a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.410-20.411.sql @@ -24,11 +24,6 @@ -- This block of comments will not be included in -- the definition of the procedure. -- ================================================ -USE Labkey -SET ANSI_NULLS ON -GO -SET QUOTED_IDENTIFIER ON -GO -- ============================================= -- Author: Jonesga@phsu.edu -- Create date: 2020/4/11 diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql index f734d5d51..903b6828c 100644 --- a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.511-20.512.sql @@ -7,8 +7,6 @@ Script Date: 5/18/2020 10:33:15 AM ******/ DROP PROCEDURE IF EXISTS [onprc_billing].[OGA_RemoveRecords] GO -SET QUOTED_IDENTIFIER ON -GO CREATE PROCEDURE [onprc_billing].[OGA_RemoveRecords] AS BEGIN diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql index 6098e39e9..1f2a9f0bd 100644 --- a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.512-20.513.sql @@ -1,11 +1,8 @@ /****** Object: StoredProcedure [onprc_billing].[oga_InsertRecords] Script Date: 5/18/2020 10:35:50 AM ******/ -SET ANSI_NULLS ON -GO DROP PROCEDURE IF EXISTS [onprc_billing].[oga_InsertRecords] GO -SET QUOTED_IDENTIFIER ON -GO + CREATE PROCEDURE [onprc_billing].[oga_InsertRecords] AS diff --git a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql index 1b90268e4..35bbc3d6b 100644 --- a/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql +++ b/onprc_billing/resources/schemas/dbscripts/sqlserver/onprc_billing-20.514-20.515.sql @@ -1,11 +1,6 @@ -USE [Labkey] -GO /****** Object: StoredProcedure [onprc_billing].[oga_InsertRecords] Script Date: 5/21/2020 5:43:28 AM ******/ /*****Update 2020-05-21 to handle Investigator and FA Ids in Prime*******/ -SET ANSI_NULLS ON -GO -SET QUOTED_IDENTIFIER ON -GO + ALTER PROCEDURE [onprc_billing].[oga_InsertRecords] AS diff --git a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java index a5557ca1f..706caf3dc 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java +++ b/onprc_billing/src/org/labkey/onprc_billing/ONPRC_BillingModule.java @@ -80,7 +80,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 19.411; + return 20.517; } @Override diff --git a/onprc_ehr/resources/queries/study/Histology.query.xml b/onprc_ehr/resources/queries/study/Histology.query.xml index 9e8f7bc6f..d8519b8e7 100644 --- a/onprc_ehr/resources/queries/study/Histology.query.xml +++ b/onprc_ehr/resources/queries/study/Histology.query.xml @@ -8,9 +8,12 @@ - + + 80 + Date + 130 false http://cpas.labkey.com/Study#VisitDate @@ -22,9 +25,11 @@ Sort Order + 50 Organ/Tissue + 80 ehr_lookups snomed @@ -48,7 +53,7 @@ - 110 + 700 Diagnosis urn:ehr.labkey.org/#Remark textarea diff --git a/onprc_ehr/resources/queries/study/Pairings.query.xml b/onprc_ehr/resources/queries/study/Pairings.query.xml index 3f4f573bf..cff5930aa 100644 --- a/onprc_ehr/resources/queries/study/Pairings.query.xml +++ b/onprc_ehr/resources/queries/study/Pairings.query.xml @@ -30,13 +30,11 @@ PairingStartType value - Start Remark - 50 - + 300 Divider Goal @@ -88,11 +86,9 @@ End Remark - 200 + 300 - - true Housing Type diff --git a/onprc_ehr/resources/queries/study/Tissue Measurements.js b/onprc_ehr/resources/queries/study/Tissue Measurements.js deleted file mode 100644 index fdc915f8c..000000000 --- a/onprc_ehr/resources/queries/study/Tissue Measurements.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2013 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -require("ehr/triggers").initScript(this); diff --git a/onprc_ehr/resources/queries/study/Treatment Orders.query.xml b/onprc_ehr/resources/queries/study/Treatment Orders.query.xml deleted file mode 100644 index 67ffea702..000000000 --- a/onprc_ehr/resources/queries/study/Treatment Orders.query.xml +++ /dev/null @@ -1,181 +0,0 @@ - - - - - /EHR/treatmentDetails.view?key=${lsid} - - - - - - - - - - Begin Date - yyyy-MM-dd HH:mm - - - End Date - false - yyyy-MM-dd HH:mm - - - - Charge To - - ehr - project - project - - - - Category - - ehr_lookups - drug_categories - value - - - Depending on what is selected, the treatment will appear on a different schedule (ie. Clinical, Surgical, etc) - - - Reason - - - - Credit To - - ehr_lookups - medicationChargeType - value - - - No Charge - - - Short Name - - - false - Treatment - - ehr_lookups - snomed - code - - - - Is Billable - - ehr_lookups - yesno - value - - - No - - - Qualifier - - - Frequency - - ehr_lookups - Treatment_Frequencies_Active - rowid - - - - Route - - ehr_lookups - routes - route - - - 40 - - - Drug Conc - - - Conc Units - - ehr_lookups - conc_units - unit - - - - - Dosage - - - Dosage Units - - ehr_lookups - dosage_units - unit - - - - - Volume - - - Volume Units - - ehr_lookups - volume_units - unit - - - - - Amount - - - Amount Units - - ehr_lookups - amount_units - unit - - - - - false - Ordered By - - - false - Modified By - - - false - Modified Date - - - false - Last Administered - /query/executeQuery.view?schemaName=study& - query.queryName=Drug%20Administration& - query.parentid~eq=${objectid}& - - - - - - - - - - - Ordered By - - -
    -
    -
    -
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks/.qview.xml b/onprc_ehr/resources/queries/study/clinremarks/.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/Clinical Remarks/.qview.xml rename to onprc_ehr/resources/queries/study/clinremarks/.qview.xml diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks/Behavior Remarks.qview.xml b/onprc_ehr/resources/queries/study/clinremarks/Behavior Remarks.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/Clinical Remarks/Behavior Remarks.qview.xml rename to onprc_ehr/resources/queries/study/clinremarks/Behavior Remarks.qview.xml diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks/CEG_Plan.qview.xml b/onprc_ehr/resources/queries/study/clinremarks/CEG_Plan.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/Clinical Remarks/CEG_Plan.qview.xml rename to onprc_ehr/resources/queries/study/clinremarks/CEG_Plan.qview.xml diff --git a/onprc_ehr/resources/queries/study/Clinical Remarks/SOAP Note.qview.xml b/onprc_ehr/resources/queries/study/clinremarks/SOAP Note.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/Clinical Remarks/SOAP Note.qview.xml rename to onprc_ehr/resources/queries/study/clinremarks/SOAP Note.qview.xml diff --git a/onprc_ehr/resources/queries/study/iStat/.qview.xml b/onprc_ehr/resources/queries/study/grossFindings/.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/iStat/.qview.xml rename to onprc_ehr/resources/queries/study/grossFindings/.qview.xml diff --git a/onprc_ehr/resources/queries/study/pairingEvents.query.xml b/onprc_ehr/resources/queries/study/pairingEvents.query.xml index 0f19fd363..828e8e3dc 100644 --- a/onprc_ehr/resources/queries/study/pairingEvents.query.xml +++ b/onprc_ehr/resources/queries/study/pairingEvents.query.xml @@ -13,15 +13,12 @@ - 100 - 100 - 100 Other Ids diff --git a/onprc_ehr/resources/queries/study/pairingSummary.query.xml b/onprc_ehr/resources/queries/study/pairingSummary.query.xml index 103bd5f73..f4d62fb54 100644 --- a/onprc_ehr/resources/queries/study/pairingSummary.query.xml +++ b/onprc_ehr/resources/queries/study/pairingSummary.query.xml @@ -13,15 +13,12 @@ - 100 - 100 - 100 Other Ids diff --git a/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml b/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml index 3aca93970..067dca034 100644 --- a/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml +++ b/onprc_ehr/resources/queries/study/pairingSummaryComments.query.xml @@ -13,13 +13,10 @@ - 100 - 100 - 100 diff --git a/onprc_ehr/resources/queries/study/Parasitology Results/.qview.xml b/onprc_ehr/resources/queries/study/parasitologyResults/.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/Parasitology Results/.qview.xml rename to onprc_ehr/resources/queries/study/parasitologyResults/.qview.xml diff --git a/onprc_ehr/resources/queries/study/Pregnancy Confirmations/.qview.xml b/onprc_ehr/resources/queries/study/pregnancyConfirmations/.qview.xml similarity index 100% rename from onprc_ehr/resources/queries/study/Pregnancy Confirmations/.qview.xml rename to onprc_ehr/resources/queries/study/pregnancyConfirmations/.qview.xml diff --git a/onprc_ehr/resources/queries/study/TB Tests.js b/onprc_ehr/resources/queries/study/tb.js similarity index 100% rename from onprc_ehr/resources/queries/study/TB Tests.js rename to onprc_ehr/resources/queries/study/tb.js diff --git a/onprc_ehr/resources/queries/study/TB Tests.query.xml b/onprc_ehr/resources/queries/study/tb.query.xml similarity index 100% rename from onprc_ehr/resources/queries/study/TB Tests.query.xml rename to onprc_ehr/resources/queries/study/tb.query.xml diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.705-17.706.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.414-20.415.sql similarity index 100% rename from onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-17.705-17.706.sql rename to onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.414-20.415.sql diff --git a/onprc_ehr/resources/views/Covid19Scheduler.html b/onprc_ehr/resources/views/Covid19Scheduler.html index d7fb324f4..f618dec2e 100644 --- a/onprc_ehr/resources/views/Covid19Scheduler.html +++ b/onprc_ehr/resources/views/Covid19Scheduler.html @@ -28,7 +28,7 @@ _grid = new LABKEY.ext.EditorGridPanel({ store: new LABKEY.ext.Store({ schemaName: 'lists', - queryName: 'Covid19Testing' + queryName: 'Covid19TestAdmin' }), renderTo: 'grid', width: 1200, diff --git a/onprc_ehr/resources/views/animalHistory.html b/onprc_ehr/resources/views/animalHistory.html index 6cc9068e0..7c9d29ab9 100644 --- a/onprc_ehr/resources/views/animalHistory.html +++ b/onprc_ehr/resources/views/animalHistory.html @@ -13,6 +13,7 @@ defaultReport: ctx.DefaultAnimalHistoryReport, defaultTab: 'General', showFilterOptionsTitle: true, + clearBetweenClicks: false, filterTypes: [{ xtype: 'ldk-singlesubjectfiltertype', inputValue: LDK.panel.SingleSubjectFilterType.filterName, diff --git a/onprc_ehr/resources/views/onprcMenu.html b/onprc_ehr/resources/views/onprcMenu.html index 7ba08712c..fe9ff8159 100644 --- a/onprc_ehr/resources/views/onprcMenu.html +++ b/onprc_ehr/resources/views/onprcMenu.html @@ -109,6 +109,22 @@ }] }); + // Ensure proper layout if webpart came back from the server after the menu item was already collapsed and didn't + // render to the desired size + var menu = div.up('.dropdown'); + if (menu) { + var obs = new MutationObserver(function (mutationsList) { + for (var i = 0; i < mutationsList.length; i++) { + var mutation = mutationsList[i]; + if (mutation.attributeName === 'class') { + panel.doLayout(); + } + } + obs.disconnect(); + }); + obs.observe(menu.dom, {attributes: true}); + } + ONPRC.Utils.getNavItems({ scope: this, success: function(results){ diff --git a/onprc_ehr/resources/views/quickSearchonprc.html b/onprc_ehr/resources/views/quickSearchonprc.html index 2e3c111c9..539a4c321 100644 --- a/onprc_ehr/resources/views/quickSearchonprc.html +++ b/onprc_ehr/resources/views/quickSearchonprc.html @@ -312,9 +312,30 @@ } }); - Ext4.create('onprc_ehr.panel.QuickSearchPanel', { + var panel = Ext4.create('onprc_ehr.panel.QuickSearchPanel', { // hoverPart: HoverNavigation.Parts[webpart.hoverPartName] - }).render(webpart.wrapperDivId); + }); + panel.render(webpart.wrapperDivId); + + // Ensure proper layout if webpart came back from the server after the menu item was already collapsed and didn't + // render to the desired size + + var div = Ext4.get(webpart.wrapperDivId); + + var menu = div.up('.dropdown'); + if (menu) { + var obs = new MutationObserver(function (mutationsList) { + for (var i = 0; i < mutationsList.length; i++) { + var mutation = mutationsList[i]; + if (mutation.attributeName === 'class') { + panel.doLayout(); + } + } + obs.disconnect(); + }); + obs.observe(menu.dom, {attributes: true}); + } + } \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/TreatmentOrdersClientStore.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/TreatmentOrdersClientStore.js new file mode 100644 index 000000000..95708012b --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/TreatmentOrdersClientStore.js @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2015 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +//Created: 7-29-2020 R.Blasa + +Ext4.define('ONPRC_EHR.data.TreatmentOrdersClientStore', { + extend: 'EHR.data.DrugAdministrationRunsClientStore', + + constructor: function(){ + this.callParent(arguments); + + this.on('add', this.onAddRecord, this); + }, + + onAddRecord: function(store, records){ + Ext4.each(records, function(record){ + this.onRecordUpdate(record, ['objectid']); + }, this); + }, + + afterEdit: function(record, modifiedFieldNames){ + this.onRecordUpdate(record, modifiedFieldNames); + + this.callParent(arguments); + }, + + onRecordUpdate: function(record, modifiedFieldNames){ + if (record.get('code')){ + modifiedFieldNames = modifiedFieldNames || []; + + if (modifiedFieldNames.indexOf('code') == -1){ + return; + } + if (record.get('code') == 'E-85760' && record.get('remark')== null){ + record.beginEdit(); + record.set('remark', 'Please make a clinical prime entry at each administration once the administration is complete.'); + record.endEdit(true); + } + + if (!this.formularyStore){ + LDK.Utils.logToServer({ + message: 'Unable to find formulary store in DrugAdministrationRunsClientStore' + }); + console.error('Unable to find formulary store in DrugAdministrationRunsClientStore'); + + return; + } + + var values = this.formularyStore.getFormularyValues(record.get('code')); + if (!Ext4.Object.isEmpty(values)){ + var params = {}; + + for (var fieldName in this.fieldMap){ + if (!this.getFields().get(fieldName)){ + continue; + } + + if (modifiedFieldNames.indexOf(this.fieldMap[fieldName]) != -1){ + //console.log('field already set: ' + fieldName); + continue; + } + + var def = values[fieldName]; + if (Ext4.isDefined(def)){ + params[this.fieldMap[fieldName]] = def; + } + } + + if (!LABKEY.Utils.isEmptyObj(params)){ + record.beginEdit(); + record.set(params); + record.endEdit(true); + } + } + } + } + + +}); diff --git a/onprc_ehr/resources/web/onprc_ehr/form/field/onprc_SlaCensusConfig.js b/onprc_ehr/resources/web/onprc_ehr/form/field/onprc_SlaCensusConfig.js index 7272dbd3d..6e11dd97a 100644 --- a/onprc_ehr/resources/web/onprc_ehr/form/field/onprc_SlaCensusConfig.js +++ b/onprc_ehr/resources/web/onprc_ehr/form/field/onprc_SlaCensusConfig.js @@ -110,18 +110,13 @@ Ext4.define('onprc_ehr.form.field.onprc_Species', { } }); -/* - * Copyright (c) 2016-2017 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - * - * @cfg pairedWithRoomField. Note: if true, you must implement getRoomField(), which returns the cognate ehr-roomfield - */ + Ext4.define('onprc_ehr.form.field.onprc_Roomfield', { extend: 'Ext.form.field.ComboBox', alias: 'widget.onprc_Roomfield', initComponent: function(){ + var ctx = EHR.Utils.getEHRContext(); Ext4.apply(this, { queryMode: 'local', nullCaption: '[Blank]', @@ -134,6 +129,7 @@ Ext4.define('onprc_ehr.form.field.onprc_Roomfield', { valueField: 'room', store: { type: 'labkey-store', + containerPath: ctx ? ctx['EHRStudyContainer'] : null, schemaName: 'ehr_lookups', queryName: 'rooms', columns: 'room', @@ -153,3 +149,43 @@ Ext4.define('onprc_ehr.form.field.onprc_Roomfield', { } }); + +Ext4.define('onprc_ehr.form.field.onprc_RoomfieldExtended', { + extend: 'Ext.ux.CheckCombo', + alias: 'widget.onprc_RoomfieldExtended', + + initComponent: function(){ + var ctx = EHR.Utils.getEHRContext(); + Ext4.apply(this, { + queryMode: 'local', + nullCaption: '[Blank]', + expandToFitContent: true, + typeAhead: true, + matchFieldWidth: false, + anyMatch: true, + displayField: 'room', + forceSelection: true, + valueField: 'room', + store: { + type: 'labkey-store', + containerPath: ctx ? ctx['EHRStudyContainer'] : null, + schemaName: 'ehr_lookups', + queryName: 'rooms', + columns: 'room', + sort: 'room', + filterArray: [ + LABKEY.Filter.create('dateDisabled', null, LABKEY.Filter.Types.ISBLANK), + LABKEY.Filter.create('housingType', 589, LABKEY.Filter.Types.EQUAL)], //Rodent Location + autoLoad: true + + } + }); + + this.callParent(arguments); + + + + } +}); + + diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js index e382e92f8..6cfa44050 100644 --- a/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/SurgeryBlood.js @@ -18,8 +18,14 @@ EHR.model.DataModelManager.registerMetadata('Surgery_Blood', { } } - } + }, + 'study.treatment_order': { + enddate: { + hidden: false, + extFormat: 'Y-m-d 23:59' + } + } } }); \ No newline at end of file diff --git a/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js b/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js index 3836ef78d..1afd6bb3c 100644 --- a/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js +++ b/onprc_ehr/resources/web/onprc_ehr/panel/EnterDataPanel.js @@ -3,12 +3,13 @@ //Modified: 7-17-2017 R.Blasa Ext4.define('onprc_ehr.panel.EnterDataPanel', { - extend: 'LDK.panel.QueryTabPanel', + extend: 'LABKEY.ext4.BootstrapTabPanel', + autoHeight: true, + layout: 'anchor', initComponent: function(){ Ext4.apply(this, { - items: this.getItems(), - minHeight: 200 + items: this.getItems() }); this.loadData(); @@ -49,7 +50,7 @@ Ext4.define('onprc_ehr.panel.EnterDataPanel', { }); }, this); - var tab = this.down('#enterNew'); + var tab = Ext4.ComponentQuery.query("#enterNew")[0]; tab.removeAll(); tab.add({ xtype: 'ldk-navpanel', @@ -57,38 +58,71 @@ Ext4.define('onprc_ehr.panel.EnterDataPanel', { }); }, + onSuccessResize: function (dr){ + var width1 = Ext4.get(dr.domId).getSize().width + 50; + var width2 = Ext4.get(this.id).getSize().width; + + if(width1 > width2){ + console.log(width1+'/'+width2) + this.setWidth(width1); + console.log('resizing') + } + else { + this.setWidth('100%'); + } + }, + + getItems: function(){ return [ { - xtype: 'panel', - bodyStyle: 'margin: 5px;', title: 'Enter New Data', - itemId: 'enterNew', - defaults: { - border: false - }, + ref: 'EnterNewData', items: [{ - html: 'Loading...' + xtype: 'panel', + bodyStyle: 'margin: 5px; padding-top: 10px;', + itemId: 'enterNew', + id: 'enterNew', + defaults: { + border: false + }, + items: [{ + html: 'Loading...' + }] }] }, { - xtype: 'ldk-querypanel', - bodyStyle: 'margin: 5px;', title: 'My Tasks', - queryConfig: { - schemaName: 'onprc_ehr', //Modified: 3-27-2017 R.Blasa - queryName: 'my_tasks', - viewName: 'Active Tasks' - } + bodyStyle: 'padding-top: 10px;', + ref: 'MyTasks', + items: [{ + itemId: 'MyTasks', + xtype: 'ldk-querycmp', + cls: 'my-tasks-marker', + queryConfig: { + schemaName: 'onprc_ehr', + queryName: 'my_tasks', + viewName: 'Active Tasks', + scope: this, + success: this.onSuccessResize + } + }] },{ - xtype: 'ldk-querypanel', - bodyStyle: 'margin: 5px;', title: 'All Tasks', - queryConfig: { - schemaName: 'ehr', - queryName: 'tasks', - viewName: 'Active Tasks' - } + ref: 'AllTasks', + bodyStyle: 'padding-top: 10px;', + items: [{ + itemId: 'AllTasks', + xtype: 'ldk-querycmp', + cls: 'all-tasks-marker', + queryConfig: { + schemaName: 'ehr', + queryName: 'tasks', + viewName: 'Active Tasks', + scope: this, + success: this.onSuccessResize + } + }] },{ title: 'Queues', bodyStyle: 'margin: 5px;', diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index 4a418588d..c1e981e77 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -115,7 +115,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 20.414; + return 20.415; } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java index 2bb208325..3ce62f3ba 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java @@ -40,6 +40,11 @@ public TreatmentOrdersFormSection(EHRService.FORM_SECTION_LOCATION location) setLabel("Medication/Treatment Orders"); setQueryName("Treatment Orders"); _showAddTreatments = false; + +// Modified: 7-29-2020 Set Remarks information + setClientStoreClass("ONPRC_EHR.data.TreatmentOrdersClientStore"); + addClientDependency(ClientDependency.fromPath("onprc_ehr/data/sources/TreatmentOrdersClientStore.js")); + } @Override diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java index bd6c974b3..fca428a71 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java @@ -157,7 +157,13 @@ private TableInfo getTableInfo(String schemaName, String queryName) if (_cachedTables.containsKey(key)) return _cachedTables.get(key); - UserSchema us = QueryService.get().getUserSchema(getUser(), getContainer(), schemaName); + Container ehrContainer = EHRService.get().getEHRStudyContainer(getContainer()); + if (ehrContainer == null) + { + // Fall back on the current container + ehrContainer = getContainer(); + } + UserSchema us = QueryService.get().getUserSchema(getUser(), ehrContainer, schemaName); if (us == null) { _cachedTables.put(key, null); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java index 23d09c6c4..f545ef489 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java @@ -1513,7 +1513,6 @@ private void customizeTasks(AbstractTableInfo ti) updateCol.setLabel("Title"); updateCol.setHidden(true); - updateCol.setDisplayWidth("150"); updateTaskId.setLabel("Task Id"); updateTaskId.setHidden(true); diff --git a/sla/resources/web/sla/window/AddCensusWindow.js b/sla/resources/web/sla/window/AddCensusWindow.js index d4d306f98..ec202d7a8 100644 --- a/sla/resources/web/sla/window/AddCensusWindow.js +++ b/sla/resources/web/sla/window/AddCensusWindow.js @@ -17,6 +17,7 @@ Ext4.define('SLA.window.AddCensusWindow', { MAX_RECORDS: 350, initComponent: function(){ + var ctx = EHR.Utils.getEHRContext(); Ext4.apply(this, { title: 'Choose Location(s)', modal: true, @@ -39,39 +40,15 @@ Ext4.define('SLA.window.AddCensusWindow', { border: false, width: 400 }, - /* items: [{ - xtype: 'ehr-areafield', - multiSelect: false, - emptyText: '', - fieldLabel: 'Area', - itemId: 'areaField', - pairedWithRoomField: true, - getRoomField: function(){ - return this.up('form').down('#roomField') - } - },{ */ + items: [{ - xtype: 'ehr-roomfield', + xtype: 'onprc_RoomfieldExtended', multiSelect: true, addAllSelector: true, typeAhead: true, emptyText: '', - // showOccupiedOnly: true, fieldLabel: 'Room(s)', - itemId: 'roomField', - getStoreFilterArray: function(){ - var ret = [ - LABKEY.Filter.create('datedisabled', null, LABKEY.Filter.Types.ISBLANK), - LABKEY.Filter.create('housingType', 589, LABKEY.Filter.Types.EQUAL) - ]; - return ret; - }, - listeners: { - change: function (field) { - var areaField = field.up('panel').down('#areaField'); - areaField.reset(); - } - } + itemId: 'roomField' }] }], buttons: [{ From e6bf4415347a2d8319ce76e10ba19373c2aa091d Mon Sep 17 00:00:00 2001 From: Binal Date: Sat, 10 Oct 2020 09:02:46 -0700 Subject: [PATCH 17/49] Merge from onprc19.1 r.64748 -- include missed .gif file --- .../web/onprc_ehr/icons/PrimeSlideImage.gif | Bin 0 -> 222600 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 onprc_ehr/resources/web/onprc_ehr/icons/PrimeSlideImage.gif diff --git a/onprc_ehr/resources/web/onprc_ehr/icons/PrimeSlideImage.gif b/onprc_ehr/resources/web/onprc_ehr/icons/PrimeSlideImage.gif new file mode 100644 index 0000000000000000000000000000000000000000..c245471536f2c888592a3016df02b0e0add67d77 GIT binary patch literal 222600 zcmW(+WmFW-+g-XF>26qh0cq)OSURK@L_k6X30<0{8PTxpg{mM1b~JE&?o@pivO?e-!-3I0z1azyWYL0QDaua3BB<1i^t2I1mm8qToO@91MViL2xhx4u-?Q zC^#4mhXUYG5F84DL*Z~J3JyiX5db&>1V=#N2sj*pf+NuI6##q%1Yd!`SK#m!6nq5@ zM+4w!5F8DGqv3Eg3XcAd{r|)Up#TsR0FDBn{u2WQ1fYN*6cB;}!cjmJ3W!F50VpsC z1%{x&a1Q-5g@&Th2ml%ZLL(q(1RRY(p%G~G3IM$V zLa#v3D{%A*3cd2bWd9lMKehj({J*;YKl%T={{K6CG~kYaNvo-NI0Bzaz;>dkWHg4H zQzu`mxpXX^4&<>t(OmX9nN2m0NxP+dGM VLRDUF`X^yJe9BAS~-&^?SHX7*;+MM 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⋙*W=&!Ph-$vK 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 z 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

    Z7QXSWE?M80XDwdVY5$&aSKL|;S+%wlu%WOA! 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�>ky=>LWZKBQW%rF|zQqEh3qwj^Hu=T8pSz(@DR%(IVFE!#E zLQFy;Y0lhe7ESHkLT-XhEY?a)m-&!WjvBg}C5d?yV~VR-m6F$wH+(z!}5?9^!QKG7>Qqjoi_?izD?*EyiH7@R2#Mr0p?iIFEjdrZ(=@mSR7wy7s z^A6Y5deOzKC=8q_SrD8LVG@V+?AQtEia;Sp{+}3Fn`e{>s$>AZ|w9A$YAX+%m8GDzH|`Zp_4O2>ll$ z>g4~8EC45|@7mjzUggFTF90~!*ZN*UGVB3!6}v9*33pQi!^}1vQkJ?%NQ@PoHJ=Xp z?f->sDF!V(m93r%uZ#4b;eIVojTOYCrjgkg30rFdqwo@YlW9>b@Otc{iQ|qMXyzf? z$!hHAURI%zUL0j88iV>7{IX0)P#Pu+6Y;1i3B~%ke6y@b(C+lvE^; zKq*=D?blvWk%W-4R_VIcsooy%*r4nE>RKHkvBN6y97D1m)v?R;)zr}t9WC9XX7!(B z;pSL$-N;!oJryF-UE=A`Lnjy3c5+k=i85VTGS!(Y&b)02M{+IC6ucH;$GxQEKC&(Q zauH2#^d4R#yQ~TS@-e&YwAyVi^UoVQ(BmR=G*b}tUXU@<&n#Q3HB0k0(+~Xr8V@t? zPve3XH!6|HN@QyL04yJrDHu{4@Jtv%^00LR0kaP_q)bSw^?fMrU*yb@X+D^hb-dN0W3& zm-I-RbV`5Nb&_;Tv-C@^bWC^jNz=4S*ECAwv`a&S7#M(@t(i)5bWnS=P!sh~8+B15 z^-(KzQZw~ZJ9Se-^-~-5O|My4{Ip0%byiEYR&(`Mdv#ZX^;e5^Sd;Zwn{`>E^;xTR zTC??9yLDT`^;^qzT+{Vj+jU*z^8}?!UBX(jd_F^-3 zV>|X^Lw00K_GD9bWn1=TV|He1_GWW-XM6T%gLY_(_Gpv#WH+?nh(%6_gh&iTYdhRP zB%f2TwrsbyK)iNN)OKvUHg4N?MD(^u@b*%~_G2HXlWu!AdH=R?%Qkk8cXNmLY%3LXi#K||cYIfO zebe`FyEb#@_j*S}d-ped-?nZCw=1q~fFE~rySH-#_N;FcZE;5e6zQGf4F!j_=Y#QhL`w#?>Bhkwt}NLhgW!n>$i#jmv@T0xP^B(h{L#f zi#UU`c#khQeuub^H~4?sc#U`Wh|~9p&$yAhc#H4&c<*Eh5mH#$^=eU1E z`HyqChZA{>KY4~Lxr`I}jXSxPclnrmxr}ePj$`?SM|qAncbhAB4o^-d^n_1;*q-yb z2l+Xm^Le1J8KFL;9xsQKFOjp^tj1m-?xL`mD>ktJk`!%Q~kM`m0NNuhaUi=Q^re zy07axt_%C45BsredaVQdvfDbWBYUoIda(Pnp&PrjuX?N>5BsY>`?WXwv=ckD`+Bu= zd$=q6xm&xqL%X)aI#`_lwmd_FviC%w@Ac$O zqdd!F`@xs|&FlQk)4SAHJ=Bjp!e>3v^SslGe7Xz0)yMqTkNwg={n9Ia)(1V&1HH6| z{kJDQ#%sOG=X}?X{nS(a-LJjbU;WchJ>R$d+t+=m!#g06{J0lAvqyWoD}KB0Ji9yo zy03gau-d#w{kEt7`>#)a&pUp$cYEhc{-O8Yyo0*jCp+kiKG!ckxUYVyd;8`?zU+rS zx*vO^$NuXx{^RSu>tns`GyB3*KFVi)wDUUW*M9G-d*>&9;wwMyqdV&RKJSw|?XNuW zE5GgI`#ty3IpuuRuYIwz{oKR+$sc{q+db5u!tl5%&QYcJSdvjTtA3L`d=^ z$cq+3qEtyTBSV-QW72$C@#agLHATW)+4AQ^p)xVDqM0Q&6_m?ki4_))XU%|gY4@G=@x9h&F>v`^-dp2<8$dkjCjv8(0<#vS=pFZ3= zb>qdWZ-@SSd+_tz13wRM{y2Q?@5N)kK9_xX^6}@Jj_!Ux07JX4wfqQtO~C%}6D~Xc zibLx;`PM2>yaanwPol^;+mOQ!I|P6j+C(e}8UhI_5h|X(3QHMi5JFL{ow73wEE)%c zY$Fu^S*#BlG*-Y(HQp4V@~s+~%ZWM(yBcrD3ZE3yNFnJ`GQ}~Y%uhb0&?8K@<+>xQO_LmCY_0Cr8}G)b z5bcjfIGGGfro|Y26V5r;)RR9!_hZvPO#f7{NaUOpvC+Z~ZP1~PCh?HfR$287w~SzX z(5*}j;!-0WaZJr27Yp>OH(aTT)jC|0G>BL>i4`c>f?{1rj2LtUR4QGGY*Mgk-MqF= z({v;aR0=VqaH3>mrDv;-KB`g~eH>Z_T_K~hlipBAHE`T*0~cttY* z$I@21E|Dx)MN7lwH@P4uwXa_6thH3Gc_&sd$c*Vd64ZRpWb?xMwEDQndjs9q<6}=I z_svMFJCMHr^Ai(b~)rC(I&+XB)4dZcDG^7=8eUtAMib_KdpOLwnS2Hsgu z%nj|6M-}=sumb~f%)ya{C~R(b`WEbf@uisIDdAgaRv4RpJWlQ+FSImcBiGy}U*|o^ z?n+k_`cXLtgR8~0%~aUwsv(aXv1Li*hSt7+f=d%ZQ- zyLFdZE7f%usBH&t{k3V^2l|}(>3M41Xj-=#9rW+fB45Lv<>%SC>2R+P;@x6b)VGq4 zM%6I)1CYkJ7cIFN$V=C{ipnI1zyp0pH+7;K{xJ0}hve;DS<1v?*yXyTRgEE(>(Ac| zwi+FEPhwVj7c}DayAp;Dan>1V6^mo0eMQC{q1WnLpHa*96uyi0f z;FNCYKqi{+a((hj@@Dq3O*PL-(XbM{s3ScEX-|SM6V}jfNE9Bng?w(wld*D`BR8sV zdr?$RT`;FYN;$85hN=`n;H9Pc{jpUbBI2)T!Z^TP36bzxMyw{27{(m`N{2v+WKVtvJ7`YrjaQbCE_?&57^DkUyIy_KK`~0HU`mU z*ULz=g1J8KIcs^8(IiN|$tku423KGV+#$L6PMy$0i(5?OKBy@t_7&}t<0~X169UGI zpo?+1;U}_66G||GuxhM)SKjcM5LO;3U%)D8V}`i5Xv9k|D1z5MxX7+5A%&Q`x~8TQ zXr$AbsdnhZ4MK5bIhno2SIK(RD`VQYAl@`ApZm!-BlS|qEb^BBn8c>zBq@_hZgh&f z)EOYD%9;9oa57Zf%|0*z0IzE4irBnP3jO7sBI2xOPbA}j6k3FT1C57 z@O{`it57gVLcPK2g3a7Ym7uYYUM|!wEgVU_hT+wG(jya^c;;}tstJuC@-$q$U}f`0 zj19s@A1VOA4+x^z``xLD^4ios!T^8+kQ1&D6jgEpH;gT@OR=jV;bpx_46Qa0h^cC= zR|AmGy)Hu-jxFn+l;K&v2G)-4s_b5=CZOON#H5)ZhH=?LkII%PUZ#DkcanxbJwbc)uE%H*R|+MOu>g2J-BGim+}ZduqTx=DaCOc-q^ zs=U`SD3QdFBTLkYI||P-I^?6dv?WP2Ye8K`!!ySmGDWSFi4}Zx1svYul#^;fXJ*2+ z3&FCM8hk-^Wl2jIyrnON+)NDL63l5JmNBce4+yLIj&GF`9#3=3yh#E8GQePZGN+oX zUAWB!iPwvNrsR@hw#$L>>X?fX$;?3p&+2V07n#i9DVJ6mjRn9*TdGF_t2bFyGU+%g zD-g{}^tub1jc88o-T>I~qd8W_qJKH&ezEktsQq(_SgT%vL<9fN2=HQ&^W;c~aII8r zL=yM<$uK@cCMAcar#?;sW=(__Fg31YN@|^|0IUkZ;jYZjp!?W~rWekPhVCItv=2N7 zAgiTCBEf_L4Pt~L6GbMEUY7g8o0fOS_)Sth&=7+TzY%79zDSNgB`{dl7l7R&q~Z2; z*^vmj%zQ-GGuhP<%Tn5cw(PZ64e(VsyWMj02JZvAR@gAigVdfu_x6C zn0X5TAM7o$%Gg4L-Bsic?o{F|qECILcLmSq1bTED?iO7mzfZQV4q%DErNW= z&@~DRdrM`DU$IMnt4Dg*yXJ|su-jFNMq}YUX0=1IBEhJk}?dl|!_5Nvb>WyL;^D21h}=g@!Pu6jV-0ftqqok$US5wp` z*|YK+^fD?=vUeCPoAN26>jsuBh%-g2iLdKRU^fzQ&i@uaaf{nCF0|v9-#k;uS6M2p zUGK${L_Bj2q^orgV+`k`F?5=8kPkoMf?%pNF&JQi>nuqca|g~Q4i5hLGYztPda)zf zKa5*J^zAPzVkjE znoj57u8#oVmga5}oJntRObbS<9y%y+a?6OIh?f8QW33homv#@&VjzU}Ds7(VIZiFT z#=!XirviU)q8{*;F6IN(t(%Cfrv9RZI%pqykJ+Y(o^%AaA`k#@tIYmuJfLA1CV{&~ z&CGH}OEgY}mPSXC1)xwzpfKc|rpMA8LJ}k^RniL$*h?c8O|$4h#JFePCWV?%gjk5h zY@P@uM2ITlB^p{w44CDUZ~$>E?QcqiUB<5k1+BIm>q>G8;ZTHZ+OU%_=>&6t+SX@x zO3`WD?Y%CpqJRwQ3@&cG>g4ok-ek-ax$j`Y@B+gwXAJE4!cC9{YY5>5-HPrMRqB>{ zEeG}im@X(9^x>npD}9(nF1QK+Za|?V$Bh5(MqyT`6a(gE0OXAJ!L5WTTjnc*s*5#f zD8F*V`!0ffl8sx0#^`b`7X$0is&H;VM97v=0$DB)4J)u<$5$}S z_plAyo{^8F3jm5?ZjuFE3JXV;VHnM>9-={LD2z8at#;a`k=8_+1~Ma5kOAFgAKVKE zgsQL@N7@n%+Ln-^2BH~1a-#Mjz2JZWsRW^-Aw=4YT|ANj!^=gk>Gl>4GFI^-$H(t_ zXOWW09<7ZSa|`~iQSGv?S)Az_$0;#@5^%ODBlJ*cwn-rY$12Bck&tQXHlid^0LGQZ{l*n(%D;gs}Kv^BGffx^RO5 zaY?ZX^CL?zPSy$A+GDDE@xVNTGs|*r-VEqcPnonX4V)$!G(q~JvjF#D7{ovf(tsFd zii@-hGKc{U(4Zj;f*30E05rj~OzkZRiGp0me_CpC8lo;cNo!!tofamjB+jW&=YC$Q z#o*@A!sLf~Y%7eb169b>&Ta;C3CS{{345i5_Q3`Kzy~j@q_W65B>@NGu#wn>?w%zR zKBME5K@!A3GBnVF40Ind0S*65lq{`;DX(N0GQrC(kRB!>I}2;*)PRKO!LV91^+Xau zM`98*L7A>|1aYIVN)+7EMITz!M3HJptrHE#0MY;e0rn=)a1;%;lMoYfMa2LOR%J9b zLc5yLIZ03>h@l6GVHkP|vMf*^Do`KXO$>Ce&A?L(Qjespq(pj41gVT5QZM8XVv&Xc z4Z?s=5%EpEN;@CVf(U{}n^R1^^j$P9$g*fo#Z)p%D@1LySDZ@^i6ISk%djQ^4YX6c zJ_|+LB}2tj6LRdzurpRMDH(ut2@zsWGr?N43q=qqMA;>>xQI=C&a<`)Mz4@c?=)7L zE?t&24LX%8?o#W-QyKreGeo#b48|Zgaic^tK_okqM6uJr%CNO^AT{yK0qWsF6ZA); z^qJ}*L@i7Nk5Uu5$^g(a-}vW8!$3QE^RglmeD6^-gU|dK5_?^prz?NfRnF z29A}?)>L9C7BYGdH(FF$aph3SwJE*l6MKaN`7u?7lQ^l$Bale3IE^0A4L72J7u0Lk zz6#Vb)@Hp**yuqFayAtMaMMokt71TlMlNS*bO^UiwQLf=QY$ImF~1a|;NUB@;;2m? zjmBb6K)*3&{%2%jii8>>DlxMUlThQptB)iLADhlchYrRb1E2KHXXWrput4In{Z4;Di)-8Q@`f^DE zAtSwnEp9|>`bLi$PnQJefp+sPDx<*`A}n@qwp~7SZhAInLBU<3!EM5FnI`?uzEm=2rbu}v*DihxHp)x@U%mlZ4K@fgZQRbW_ zeTi#m7NUS-rB6<%HB5nWx>JV^X^IXboACe(}BW!lT%9gxp6ZFA) zbGB4NZk+!nH~@SrReDzYuC%x?%x5j~g?+Z=_5loNSFqZahb0mehU=@m$sJNQU z57}}RtMCosj{0^H<80}eH0=O%nfMu&lm8w|se znT!9kOf4ZS2DYSFV|WNrF~S_edN&uj*4V2mkc%||UQm^ITl6_8chfeDoNpjne3xb+ z3z*>+&pbn6}wBD#u;qjk9cQPV_exb{`?xQKWa3TC|t z!uqRSS}On~OVhB^A*_vAyy{MsVaxcgMKmo9Sg2=_skJtF?qXo;kh9lFx6Rzv_vSFd zTtuOx0ocA+y-E}fD$Hh0w4s|dx@xwhUk;@WPo;4q3H zf$c0S6VmI|QpFz$0?%3wiRk$NDsX?X#Oqq9Zwcgu?pa<_apjb28BSTv8cCFm4m97Z-Np>eh7v`e5Y%-0!5oz({gJ(_Ge$$s zov*M?>7nG-Sit2rr&rGAel4^jtY|s9uza+kJulLfaUj5qdDjiY-~dQ^?FRpnDYKCZ zz+=;NWA$2xxwoC^tJEN?nE7TGNqK+f2-~HY^T_};n}j|Jjg`?O>AUFm%jRsjvx&>K zm1(%xi|&%?luK$K3>-4HY&+jg>RuKAPOeHEt6`~ez1r-%2BHo@d>>d_ku*5aE=aVR z5mYrx#FpXR7|Fc%=FHOhy|(kp`D-!|Vu*EnAMkg`s?ZCs6~V9Y>=voD;LJx=C>mbw zZX4;Vl2Mr=4YwAxDJgg#BvYX((-8%;yy2}GKk5d|oRtHomJb!eOL7A@uA)h*y>GT2 z&YFAM_W*uPhd~&z;$^ZXp}}4I&c||e`N=^4hS)((CoPx5jucRFws`-kaja1)Oqwp* zrp)+C`;U?@uvAy%U>2{h5Hsm+m!!{kj;_i>+N&%uS?l;pV}Jlv&Qq}G$5Nx6%BD;v zDU|>j{ZQ*61ZR(h3XjGmSkAFM9W9YzLd?|dBpUwWMiY@fhe59jyJ{3NVmGj*921)< zZ&TW}gv_fDxN@6mEqw`ak_+B?6lgn6v_7k5VGnpwP>tVtmrfAQs!+xmJypyz5Ya6- z=SC4@<>dphwPc{pM2o{Z4$n|J33VOBTjb2}N#&y+6}9irQ&=NTIiJAnAK`hF=LYAM zw6~VQ09Sz109?&RZ=54|Zp>4Zde0{G=H-MG!{AKQaIjA<{ zJOZ`v2yu6F7fdbxvgr$RfYZxJ^M(p>&a1Gbu`GD30~f86YuD{qWYgDx1I1B@q|9MS{)kR2@=NW#haqS43+Q=mA|q(?D_L8bLR$ zA3FC-KA`~s?a4aASa84uPr0rXrB#UZw|tEwa=$)%zu>@1rkohp&X3luKx*wR@o6_v zmfL#K9mfBr=3F{j6s7;Q@3IaA=!qBUFkWLom7(wh+niX=(Tp~I0+(U#?T6Ky>JnZiN~ zdv@(IeUf4@WZa^nE-GAeyp$VF2J5Dv@wlnEMtUAQm;JzJ;J9 zE~}_%t}w*WM3>b9K#jq}0YnqL0U(Xok0%*pbQq11WPxS%RZKH<*}k&$qHU@DdLc`P zekB|HY;mUV16L*PTRsLRF=eD3VnSSeJobV6V6-+kGMes*^qh-aRu6W<=aJJWjt}6r z^N;gDG|)kFJ+>SU`mFWXX$-YT7)c&!_m>QUJ+|&p8fBdpfMfNjXIn7?KGYy?dr3AF zG^9xcTSxUI1DIpVP*)mDsVR04XaX^Y17~MF7Fli4)FV+!^F1~keSc}99zl_fp%`8O z!~kP@wXrymfDtYvP)=vD7i58%Sp?xg`Y7koJ;U$Dya5CQQCr z4;m(-m|DbS;%Fw5aQ0VVEJ@@d0H6po9;E|C!wX_5QJIEg zYY|yjY7MosP)Eyrii1gKLG>37q>`B;Zu?X;$v(@BC)9T=>4hh5wf4l+GINd@5K)c;m%ZMD@E)uTwFrlt&RJ-P>&NBTrI8D^R2RpN+oirFP-5_t;hOxxnt z<4X7@g_FK%>AO@`M+ID!PG6xn2>@2+J5^f>54bbU21c+6)S{M;v4#e4gA&Fnd&x0|7;%9* z=a6vKMHj=eF)lYMJsPcBqLX!nq)=mMK}lhodf8@`GGVB@*AMkT!`Lz)CHL0>0tIOG zUgw<^5p8q-x6h|_kF=tlwXL)aV=&6t@_2azki((nt0<9E<|ZVmIDCCT=d-eY-Bft`rwem;9zxOkNve!44Lc`s@boy z`mx(lLPO;;P40uDMbI70X+8NV2n~Ok!c@^nVJW!JFgH|GA~6N(w2yDUU(~6hA2SaC z3dHxU!l9+{C|<+^A`jIu1x+lN!!c z4}de-$0UAKB9QE3JYQ=ITB7ln7=Q#igz?s6)bobNEaG&;8B2&la+YL4Z7V24VeqcS z!yfvuhX5D`jE1C>hr#TPqP?M+8agS+|5d#{;fS4FL|DbFCKIf}dO5)Jjpz?QbeWg0NF3=&33Fy@>d3wMJM!Z9v;ABj!?z&XW9paBgZ z!%{sWs0?9Y1VVSwix^-ONx6})EQE22M-C#d$!Vt|V?c>UHpEICHM8hQF(*Gt7 zhK45cdkhr;!@*d|2$bppfEY6ROpJ_FGF$l`-r&-<+k6WmnF)-dz6Y40d`e2_(aRfH zmJ%$cWP4)SmYbq@&j)euIcR$6x$5DofBNW6o3qIE_W8SvR)nMVV9hb>5eex)O&Q{9 zj3Xb(7lQC-Wdk`3PzjPtDM~ST%L$=cgtm;g4aI3-6021kLPXOsb)+!j>Z^XDAjMY5 zbi+bVMJR!i$OIr0Q>14^;j}DDJ~fPHp_iee5yT&w_Ozyj3tCF{5^kwS4V7aIBY_!! z6Pn9L%J7|W`XZvb5C&+}0mae|=FpL$X;}`Di6GZFN2IJ#Vj_geRz!G4ivM|JAAA~0 zR+t+w=IYV8c?6_FXEI)lL067=Z0>iHk`ud#W=^X$N|F2ov>y4Ecejb;Q=uBPD)DoX zy^YaCJ8~(jU~;uGl3{2E#8c^9(Ou6gjG7QbL<3a`m z9!nDJOp7?L9s;D~U1F97n;b`7u?%fMEfOGFQOBIpq-vBrT&}=v3;#!Rp7Fgtf;i5g zBusd!70S><4?c-Q=wS>H z6*Aog&q7LPajw*#-t{y@iVD?o;8)5vP3kdy;ZH}Rqt}LDW?5va;XUt zhxvQOno3_xdP|NOiOA7$s$=V5NxK2(UK+}q1kDHumBmmq@8Q+Od0Fni-Kvg7G zAT(Zl&wZKb7HnT8GgiJ7sJDeKsQMlk(HZ0c~OW&fo?4@FjYU_nGRWp4KJ9HQ|S zJLGN<$Zl|PJ^R&g`yf^+AzK4dCV&wuI<`V8bsQ@8BdN3ys)rW)0B7(78wN30==Kp# z5i9)CIn6al1W|D-H%MtiMl@(X*)?)paWPcET`ZS!P0@o6XA}!F6%S{FA;*Lj(>^B$ zKxBa|lVn^c0dK}PWdjid7r`seGE&J^5t9LiTDK*N(j)k%440xl7$H9R6)wYY7sGT; zGKMJxaw~6PB9XHX>hc4MK_&ddBC*zRMTQ(B)+Qx}VIUz87lIy^C2sHs05T9SFVqRqRALy`mW@wqmQIBCEnlcIGV-gdT5W9KPcgcQSO3qD@wnU~fc;5)?BZHHUiF zB#NG=!aV^J1L}bhh}Lz;(hKu)RSVQ(cX(FvVHRuQCKOT@F(YB;Ml~vC6;g9O zMu$j|fi_(eQWRtrjKONrAbauRSISal8zMZZ0RxVMjXSm%tJGl7;YcO3hh+$D3*kga zmy9t3H;~AO9r1k&*(b(9g6QFXyoDb5<$kXSf*e(mTNfr%H4(k0U*u+fiF6w(gdWWj zfkv5HwDw{9RexYs4@sm#&U6422n{S2GyjiYzSCBU7A2WL48Eh46Jc}-QfJe)94bW&p0*IH zgl_ae8{Lsx3jteqVN|p@bU2_1zGHvL2t40033>q%*Aqz?hAL>Kf2v_j+MyW(fjEH^ zSHI&ZdT{_7Q7hsz2^kR?y!d}}r&4$_416+GC6r0>#3DZeDL7z^Vpb4^7b}e6o5}#3 zm{L@Yvw`9xX7jayKa!iO8E4vcoBz1+GBI-@nSh$C=1dd?f~lztnV@~7!1SH zuER2@xh^=sItf*012qgB6i>r35WaH}hp{7Us2&KQ7&YM(VN!nXuosgNaG^I>vRNDH z;$Z~`65?nvjDZGV=~1AQG%IkGWaAw5FkzEZ5NQV|q|p%zaVE;}QbamxXz)*ncM~F` zI+Dt0#9xiqwdH5?Ybx znq4DvodQYPYHcxsKI@_%XEC6AVL~N=K#XXg>kSWmxFX%HF3nqT?#6j^|9EQVxp)xB~vll2fAPj;sOSLX|Vmi{) zV6@3X2BuQ>BnCfnZ~p*@KkM=a%h5}#xfe(S9_tcnjPSB11Tq9G`=lFSBxK!%}zk&~>keQ0$Zy;gG=Rw7HQv;7en zoA6?Es|J0<6Yz>kvhfla`Wb=IC2LzJrIdUnq6rnDLR2|ElPVDjakTSE9hCd7!;yQN z$+$7LdX!kU~%*gJ&81 z!kV}i%UeE`L3OrzZWyt{wqYfsNy4{E598TsLaY;x@~s#V#MCql&La_yGDAi8nE*Kn z(7_!k)`z`S7LHQHQA$n5F${vtX*+Cn^Wnnk11nn?pB#l7jgrYvwNc2|plHCdBaz6Z z)W=A{P5+CW28|pSnftD}mBK?w!S~|G*<%*fs}+nOMUT-a&r!YPgBF<(SvdPdkxY7R zQl=W5Vvd};3>-W*OcfaM#g8FFi>k|MJf(wzQCDm?0ffvqqYtEfU7)N!5pfw9yizm) zDHM1Xyj;W@6v0+^6{%}nhO}S+R;dU4yZRh0s->>G8xp7@w~B<%Frh+%LSq7I62?g~ zFT+U2{B-3DHHrjZL>Ndx=y4dmgeV7>n87F3gAI1$0SP#^OXccEemOcE%eJlwoZFH>Pkr92y` zU;jP{(2*k>Lqb^SQO>xcLOUqKUlOEQqcfFDW$aNY#j@2l!ZJD3f>FI%@nXoa#9j79 zWAGR#ONLzS;l0LToOBo{6lfDYqCCOcb1`R5Qu3`f)jkN##>Q7+9BCdL;w+>Dgd3=0 z$3>4d<-rVQWKGNDz-U81g_lhbI$VSU7r->bVa)&Ibl zUjXH6?V~IJ22f!{Zu=W(`_+~o9nsBIxlS?M1*6eKm=tuGt8J1*tY;$5qC9_BB?WOD zwgEMCBwb|$zJ%m;96f~8brXFQM>3e$?X53d5`~5W4R8^21kRX1IVJ+!7WHC&0hie0 z`(YTQEjm75lw_$aO)~lUn2tme2Ze>>+QB^sKsIN9-7A^k zUNRTOVm^4od2LZbF>=elqSb6xt}UHtW-8_zoWgVJ+HlIUaO9ol^mwaZKICb>aDxt2 zF*lCUrMrr5=uo4sIj)p4Bts17bbCeNmkgOtuG*7iZIQ`;^mpp~1vI82a}tv< z;R~3~Uehe@FKK~YyoO$~0WRo4MGxCZSi~_%J%ikemm@b_;4U%wYl90en4|>QXQkPf z`mUcgc(<$9_q8`hwTZl+*eL_6mG7bdp^@2!a!btor zD6N&;Zt+wDPfGH(@D=!3H00-`Mmc-T~6tO($$A_899yB%i?-SepbYJa{+!lBXjY{g}3si-j%*-0D~+G zD6V(WNH;6&=GSpD2sHm7f8<_%vraAODIXE5_}WDxIBR9(pgP%RKB(g=)&HH?z+UvY z0Ts1w>zfL1P|tI>&COtR>h%(t2;XzO{=KcefM*GmyG!xH`Y;v_=Y$?|MxnoSnHGm1 z4H)hbw^c|FM$X}C@9DOf=;dAH{+2xfg-BTLWmFerjP_j7aJ~)~0UdWAmfo!%@EQM9 zk*U)*#eZ%|5(>!iGtY1e*5|hR(;cs1;NI#^-`_G9@$^?dB*$gW&zK=I=LN0(zE023 zp%(~Z=s(UAQ29*?_POEy)vQG><5qnhXii zAw6hIX?`Urv?t4b05a`^8&~dJx^?Z|#e3H+!;C@=mOaQ5utlS3trk9tbu8erG*cRV z_}Fn#jnF{8Bq)<=V9lE~^VCXED@&RCHY+o|6Rc>0rdiuWvjSRZl@5miIPi0yB;56; z{?w-e0Dx%qL|P*4)2rI0RT8gieoVxBK{FKq>u*kB?EGdRU zgO4iYHp>aDk;tQIJe&|4Xg|WEU+4E(Wv=|WQwr& z5<+uC|6Y3ON|JhN@2as#dJ3tYK$?oD7@;Cf!pAlvOd~xXd`PAeH3RIsqN<}X&Y>tY zX~Mt|oAW389K5PMi@YpwPpdF%&8@snMK#q_0U+i?sR&dQPC}P@=&#AFDzPT4T;q?> zh%WzKu&^vSw2(UIRvR$K)xf&4y6W~3BL>$5QW8LcgaIG`nd%7x0370~XCET#xotQ! zqWtx{sJ_E)SzxJxwB2`!RTt9e2wN?(<_skX$%dj?k6By^oU`9KnIz29)oxu%L@`zR zuFi?>)DkkF4ja@c(_qZ>C=^+nF+mr9&9G88A+;3a`zR*ZW4_2bFu`2cq_3+&A&QVo z`k*>!;z`$q$iAZ9+o)EH2i5e=m_5pM$%7w*@2ul0wOGmcK74H?megWWH@ zd8G>s4Fg2Hm?CIy3xKA5x(z@KF>W|s4BavrZaC%ZbQAZBKvg#>IgzDm+hXZu-NNSP zLreCF;$%I*CkX^s>qMNkNaXSIX!&A5uMKS_A*#8iE9p zB7-TzFXRza(iF55uE5P8LU|BPa;7IAO~q;^JXHOXv>$|UZC5!QioasSG>pLrJp~#I zWvb-3`$4QNZ`oWR1xXiHoiTcrD&a=B;<*(TtUdumW6)aC!7hbLSk${olc;CA>Etha z->crTa?~#GKr05-k{MsHbpXFaqg%~`Wl~-_98E0HJiy9hh2Yga*Trjl_R(kxv}G6vdYKT(SV5BHL`a6JR>f45!Iu1_iwdI6)d&coOrg?> z8q7$pFvPDN!OA3lfzW{j=PRQC1|n3dPCE65r?r(QY0#7$5G^Un^0+WY&|F6UHs_hl zF4pZre2bnv-$ud2`NU^PTM*5DcE~YaWqog|Pz)8stL|w9j2GjW&MYELQB4tcI=qOY zr1_}TvGZ4UJCI5eg_Lpfi=_lp(WXd5AFV8|Cqh(=OR*MGv)GYvO?ud4s8lp%5)&fh z^w8}`J>WLO8;IW!j3Yv7${qj1Y_Js&cjhb7Xa@fUbSrBI_4VB2s6DS#0vAp2DC=VrRp}%FR zBM4fEM#02ffCfv3Fn#DemHA%y4Ui$w%hf+s23;G$?_+s=C{0^-P6k%&H5kF*2xD6@ z`^=Mu3U&=r9c3rqW+-$ewChdDNmu_`>}DC0*Tv{@MGg55Q5;EcN>bLANr=_PnghTy z<9j0k3lyb&L!fr6;$d9^>M#`%FK-ElONn3@c3W81%E%CrPeXLi^7%z%Pngp%6rBl6I9%|;*4FQ3oOyRt6cu5W zU^+cuNH+u48~6KEZXw!|HS-cJx@TuGaqvKsY{dSQmVA*pw}bzZpAY_QPh7rSYBL^*`MU+JUF3Nv}a^!T5y-BgvA%poJ z)p%_=)T9r|t^x~5r#EU$<7ymTc#Q zlRMWt9`?>EXJ?30JC`%!_+x+`?RjCX&Mg+{Z%|!YiXIu%nCiQmq}J@|2^;GnG#MX_ zq9h%Hw{71+vaz9B9(X?Fj4vjg+v3x5Vfh_30RW`Gm0uTDbuIUSo}@#?Yqu)LaJiBa zOrz&GYZyutx1bFzoyYX9U?#;NrsNg%ZGx=;bkWP?-+FKwQNtUMhi&Kd&g10|;%3~X zc$e+Eo(9>pjM)f73ZtRfFOmotsCYDAYp!%L6tsXDJTf01d69vWt^gA@07|^*sj9TY zAr2Zo_erRR2^*<%BsG#N z&p{Fkcx50f>6OExw9xe1doR2w5A^QV0(ufU@Z)WWFVVGGPz z|Gq?w3$l8#Q=_C;2}5`L!uQF$-1?Y(lCU94HHqVpz+#PzGYS6tD`2t^P5HQxvo*db z7vN|t1b{YyNCr)Si;~!fEl@ebqB*uo8>(wIrkfW~w3qqPl^KDsyOJ4*xh5&pt-x}o z2?E3s8M!&KlERq5;lh+kgQ9fX2+nGwx48_tv#RrpKk`GO)gYh-n!6`kv0E{{53?Zb z`M?fStG-#T-@vXkQ!pJQx)QspL99Vx6g#owv7<3A$%ql&A*Tj=yTiz)eDlJpgP1+h zql6H^gNrFl!@UEUs&tu-i@6@ec zD~HpQ<3PZPtqP#d({et1(4nN>*7L-#QD&xvE^rJF1Mn zd#t3X5DIiuNeJ?;m~5`#BPNyPIpvTY*SM0!xSeAu7G;74EF&WOS+P~>B3Jsdf*BqF z5CbbR4a>>|YLl*u+$pAjx*7_iz9KK~u^p?Mw~XmEk_-#PX~9ohv4C-*H8C8WBtSA6 zkWXtau<@U1tD=};oqKeuJGnoF`YDjH%Ftny+k%*ZWH2a##_^hzu0a`w97^-*ken!! zlWG}jqR3G}6xdX0v?(TI9|o)ty4f%Z1h99B6m4Jk7K&`A_xm<_5g0^2nz z#3&?FGPhF`)GJ1g^rwQrK=fodurVr-GAocsFB&=>lp-PAGrhyy|C^*57Mk(Rl+ilY zbDCxoj3lfh!;r}lY@}h#y7CenXW5fIT_G$&!Gd#B_DQ8>@fQxd(mdoK29&U!37z&- zF^f53nu`gDui+*{lZUCWl}B`61OXfjm!=vVm2uvyWH!Y zJE_KfK)wl8#2nKwBU6S~3V`7djsW0NrU*C+u_ehPkbQ^&07wJ2fB^uAfs#SGdm5jM z%%_;5hjne97-*G@7!HmY4kaa`5P4TM*iS0eIJ1fdxa1q9xQ!bK8r~q$l(?c~u&m+0 z0b*Ft?8G8={Ejv0qJ63`>9L+rqNA*2E)cE9Li-tFIXP1q{}_MySMVtuO06hN1GB7X z3~}LzZ|VxinbN5_m`zld>O8iB5=!(WIL8niP7}H$%(Rw$pOK3WR65la$`PXILzmE_ z?c24hB@6v?AQZYm7VM@pGm{K73{uI$IsM5KgA$}m#aWv}k}xM-oLhkOQXm4Q|B}hF z@tLLCrBhW_Kk2Ba2(IR&j1%44sO1#4`Jlhyi3zfbMgfycE0_~&PE-ZA6AY|I?3X_g z&>@(U89#j& z1?!vKHJ!tOGxAalv;bX7X;tqC6v*`$_DI=KZPucrA5#OXcwrXo1)# zyWLu|TU-J(y>lBX`8I8O9N%=SdQIEwT-+wJvm)HSw1_Ws)r^q+na3of80jH+)3So8 z&pvBfNO~yk**dsUEi?5;;G*GPwHTpFj5zWy_8dr&h&w|;I_qPdku6uzE3_=6%?E4> zO4+RLM4H^Sl{vARTUDz~Y)la9#}|2(z#2RXl$BT2U^bl})U`m{Ld`CO%okbKOV2GNVmOeskT|9R^;NArXZGeb~_USkM$4{~&J+pnYkLcTIz8`Ac=NUmJwLTy4;I zje%%@i+aceaitdKEr?h=tbJS8c7@<;)Fl>~xfWsArIJn0JhFA8(rK&WR9&!0D^x1f zr~2y6%&nx>sV!&gB&E$1m%y%NFgoINlVu==e?5&Q4c#Ly2ha5kjN`qmV&RAHFt6alSl*Gl%-rvtiWhY0M&=)~+o?_pHv*%Vk$?uRPgX11&)c zkz@VbNwf<){MhDzOtx5iM=9mN-Gmfl+C^a5Jgb%CdR^bmYO1B}!p{gV;uI9aM6e(3 z$-^SetsS{Mr5Y-p91!eJ_xut4W4Qp*{|wR7nw$ENHDTKmJgjXal@6^Qg#egg$YbRz z=E)GLeNg1tG7o*A2k?!_2-#3!GTnI6P+J^>TGpZ8GD;0c@bs`Y_%na#eGzSW}sUzqc z1kAEJTXe?fBykJv!sh=aQ)(#=UHz{TR8@MAW-?u?wn!h-aO{G3k_9?Brx0Y8sFS8H zkW-Gb%0oC7RuE~o?3b`;O*$!NpS6&;Er;$Ru3>=mv8d$rJ zz$IR};m{>>v*aRZ!pTDwan3A({~qw;nT?Gk5Q1ciZ0;KZR45BP&%7gF$!XRT?JYi8 z?_M(UaFwL}EFLJxBcfWGIkb|@wRXCn8JsDQ`nhOCuw3maP~(!D zkYI|Tv7gps>dfeMeS@X5L1@^ANe}}Zm;|dEGhX$g4%kPy=-@iagU5nW^&k%U_M zi5M3b4@U!H=q}Wthe<$#G022T`0-XD98RX1fgo~v`0=VR4M`9K7AIK*sK+nO3OR}@LHbY2F{wFEVf!1Iq$j`U2~_rDK^v_Fit7X zSD`fYq_;*Q4TkAcp@WhH-{si0?jve$la#ks8%=WKv8Ob!VX;&!tP;ALU~JB=&Zh7i zgI!VC6&Fv=v?v!?g1`TorRLFC-JrkbfdgAS7u4vM1l|n*$bp2%*d@*Q+7(`FgAn2P zmi!xQ004!b6OKfW|AvSkj!EbifklmEMpF3e+tJisRCHojK~n;m8qvkxf_ZA8S5;jd zK{wr?8xabc-9?c7{89Sk@K ziV32dW4YvZmT}hA^3o-hM>Ik=u!Krg6BC#&qg0dk!|M;-_GX&DBg2iFAE0?`g216Ivq_)KX&;(^52IA3_a^crZ=z3AkOB@&v zY|&Ru7=|05rK>RXMz+NR0El6r>M1L@Oxd!1VE_QYp)49bg9Y_5ECx*(Js1Eq6|6Um zAr4}hR4@dP=3qpS1xGgASMX&=m?%4niQ#gl!H5VELR+R2n$Ch3XZFN+&?roT7!gMF z`O;}bdQJ;URi^YQQk+MbE`{keXu+FZgW`Ny52(|FKBMhyOLb?^i(DfTgnDqJKCe4b zE=yJtz?fu{7zS{uY#$?#A_oIFfHIRLhG{aP(WGxuCWdG-VV2AAfTm%@G;WNj5I~H^ zp+7Hl*BH6w+nigY%G3$g=hmq&>B5v-7pBgmSFKVNZuTkIs(Ec6#hF|$SgSqB=A6rv zFU-7KyS{A-bgAvGM|BbmF460Dt@Pvq|2`XO?3m4&(@rnl?Q!tH*Ge?M8+T0j6?YLq z)2XH3LFFw|R7~tm)m(K4vE`pq^h`M3PQ$^6(S))cSC(D^E_KjQW3h#mL~2F!-G9U( z2a`+wWi?}4zs&?7e6+z;98)J!m)3~TF(sFM17g@#Q@e?XVS(={nc-5=>6l!jDj6{RKsIqY-LJ|6)vVP<#kv)(?b;oy=! z8X@4)mRm41#zm*$kk>x16{b%#`;heKVOp4UlRhLxGh9%TmL$euu`x6dLKlRqn#&?x&zX5BUKFu+! zB422^*kXOu|6!%$cmQH|q*_v@$m4Lsa){K5Q+jJuRdA)no_RTw<=}U>9>?3tH76+K zj!Zw<9d_IWmDkH52A!mNwg#E2G9@chVzJwbE!5A(u6Uh`3IdJfTNoR4k=IvxxF4_< zdl&6kJR&I6c|q@Z9&mfn=3~rC+ZUC&Gs(zx;4vANBv%oOT^7XHMRnoDTAuleng-Sh3DcNM#4xlnoM{jg%_0re71_Va5Mxzj zg&oGwsbQst`>{IhgT`N!qEr#xruJm#cAlP85JM2X1m`3dvZq~q`_yDuScDI*7yFeT zsa${s|D70jc-AScvCv{dxyHptDeTD_Rmi3z7wJS=@(GdSWOBB%| zK=(xKHg|hU?g}S2t$~PW+aXWjl+`kK7o{dgDw(H_5SkyyP;|NfbSq+!lMo^ax3TlF zjXH${&wJ?c!u)B)h1l6g@tUcq$rS{A6Jf}EXqTZpl|^3`N{j=p61*wZtDakQrION^ zwQ^-eSj52)0ENOe)m08zUjY(xmh#5DDX5Ze@t8zF))n&wNoQiqTXND8$XXW2|BGL# zTp@=u9Gk7ISo2XTkDyqar@`-KG}CI|s&&AyJ+X3c6kwI)7@cGx5J-Qm>O@&O(!rf2 zS5EN}TOVRY{k`Qky@?ssfa6K~2@rzaF&{(aht;K4)maCsN)~a$q9N7Qp~RXSv;r6) z-2jqU1>2U~n5Gs`h6MnV;3aaC3#M_^5-cv!2pqPgx-A_hoUZ$e8X|RF*DaHG5(yqO zh@q(Cp(c!(aUSt_x24_P$(A~zhf5X$8)e{hDc(a20AyIBHJv4%+x>xIIAu7qye~gF zi%nrMw8Y6qHgCj%pSj>l%c3YnJ3-Ts%WjFSAoYzlF~SdBuUgj#?dC+w|A>Z}I^4$% zYBns`OWvBq;uF8viz>A`kWa(H%-`NB#>$8c4wUApH&BjyMXcO!4H*}R!Oe^aqX(M?{USZm}_Sgs7^7!%wQ+v&13R_L`=3v-sCY99+j&7^q0 zERxtgH6@{+PCY=+Pc;Plc*=2U6$x5gQ7|6f z30LYZjkc6bPypcBv6g{_h?^l8{P7XfNK%xMS>R1v|EmQa<0#N5`O1;x9}|(94rbJi z&{9mK7j2=x=z?hiR-;n_%O!yqzf6D%KFt;Rd~t|z|PE}$VE9Cz@b41ODBStxe*pcDg`H;}4jOLhG+aORL(HaCj2RhQtx7?kdrCr4wQX+|3{iT@- zhE&lVL`?QjDPhvBrD25G7Kc?FM}dgu)fp-Y7&!(KUR~08BvEALPu-mnSvAcO4q;R! z$emfGn0en2+7T+fNZQ><6s3qyA_oH6jmP|&DF$YkWJ!lC3(si88%z$bfds(7*FF#f z5Au{t)I+3P&7^b*x(Lrh6pu1R#9+jL|0l%`p)ka>VMZn#hG%V#B*+v+y2NFYPmPUD zI#I=C?t?zmLuOi^Fw#RkOcOD@m!d^bJ=DZT@(7`=k|>R3txckY)zPhh*34L(=g|_U zsa+_(%_m~yD^e$loS8~)8q`4%UJQ=hY)}P83izeVt-Q-w)CmhN$h&P{G>8rDP$Z*h zgfJdProhHBBu0>-gr~qkQmjx%^g;|!N+yX^)PZH$5yV-os9PAwD@vY}?GUs8AlFHpZ@_4E znw<^4SsNZ2Q|?~_65ED&7LR=7{}Q^$0o{>{c#=hxSW-pRDoxQjPGQni8kK665lv0G zAR!plC5DmM9U`1u#fR9{#Zy*HJpPe-0F!&|k!$J7=?JEsdP$1)pWwiW8blI8wBl!& zW?~53L>LMHOdDq`#2C0lG}uWDOak_x24Fm&3qAxnfsAO@)OKZwmle!w!~hzgfqVr3 zE5%$#FyligA8J430VOT5Xx*rcRHhygy^YAkM-&!Lk}VZd1qTojM^OUJ zZ{z$$&Za>8dk6e8G&O} za1N8)jKs(XZTtpUWk-Z*2-m*hmLVK>q#dkWTb(;(wN@Pgtd@WQMwNd1XzyXq?1f6&CXUPc}x<`C?Uq4 zR5jo^3Ysc`TwUg5NS@;bN*0WiMpwE;W8hFp;6Pe_?x85A@??)vm?r=@z+<|n>o|r| zq!$9Lj`&=~3XWerxXSoFo*pH~racRB#3XFlEFWPD#(Z9pOblNB(TEg9<~`l~IK?9p zo`_VPuSC*Y4#?TU*~&m&Xc3-qh!Ir%S$8s-ev8m7^(0vZT<1Xj1Nm2$gYTr$q;ggpp~%uF{rcNM#uiWgO3N(Mi1xoRy^j z`rE-K9TC!=4uyc|jyjk{rrym;2dBdS?VYBWRc%G$p5}%fVV$IbB%}dC^i@JAL$giW zVNi}sWWuy<%0DH^Y1&36EDu=>!>KgtFl|at6iS>xm_gX4CP=~Q#U1ec0#=N8q-2KO+v z=m;SGP;r=4+zCjpbri2Qu$-pB?m;LB^31!yV0K|VeC;17C=J{4X<8O zp~X%%h+6#{CKn4Jg0EdGohDNq-UUz-FG!S`#_43uWGQCJU`-B6NfMJ*M=WboEGt*s zaf@J>G7o!Zb*pUOqh{vi!F32VPe<{bzc_?(wL}FE>;gi zk%ll5sjbI?9wqQT%}nMbkG%+Q$04$6^Zs2?sb&-k&GCcTtM0w-b9>RpDO~hFJ!C#S%a4($OJvS|@(%U(uOl zmTXv4lPHNIsn(4Dm}fZ%jrt^skLZ>S*f!^iSP0HR2ML2@tCt&1lXeAh?cVC8xEfx| zgYfier!{(1;ui*?>SdAH6`;20?q1b!5Ls+<^Rr`#^MLK|*r^`aeAx{HaRAFHZS3AU zySAOJRj@o!>g1J$KR1m$UBjvN@8+NwGFnc$nYuNi)g5A1(XYr+I+SlxM&p@?f{0xh zdVZ*512r9Q-MJO@pUd_%H(hHKGx$-H%hW)GuasI-$<{~D-jq;|ScM^!{5O&)?}7HM z4b|m#qKMgr$F5}<5;B^szehcwfla)XdGE8A!z`>%a{-Oog&SvCFkSuvDMlV?OlSy{ z{;cGEoe<^!1`w_JU6IF1LFMZFb!%6gTUGmwKc|c&wAEd$p)*Z`J#cq#DPA=&s^xUf zg5>W$tiNFxJ9dl4j-CV8y2wX*mp0Tx8<3oLTJh!9pHIaiosE4@VWbOTnwKf3U#XQS zIuJ{2)zXN7{qQTA{K2_37o}zke+!0|$Fvrjqay`sT@_MQ@dTzFdw-c=Q-{09x9Fvv zOgFh(7&ubYF6(W#xlgpB%`iXn*^BUnCazVbTd0-+rmvUccvk!^@m9m}_L|`g;Jj{k zA64HOju?;z02qJ_Xh|OiprV15Lz$WBA~v|ZMZtijixH|&uFj$xU_d{j$E|9bR^qv^SLuTOv@Jco(ZaUd<5oStedbFUKq#ZPOdvsJ$_OqSco3n$ zhRW(OWJr%;M2HR}CY;ESpv8p|DH_a3Fz|*l-{{XeS*)e5p)d%!&_L5~R3N z88nRs3$E;VkSETD9vQw&ND&2E$CCBaw6sE=5H&;3}YI|dC zof0+b4IcUB#)O+moI(ZlJ`oG#B0}7P1~mS8OX}9lkZ@hpRbjjR*D5JX<<_JprBe2wa9tx)w~xaAG|V7qyG8b1 z^i)z1#_z%yO8-@}~nu`jgPP>7E+^V#0hmCl6zyx;*)CPA}xpq9brP3(JNIx`r(x3^I!@`_ZTo zv&y^EZspXcG*^9uQKRvo#Tc&0!OMtLSTFZHu%j8I?8Tn))A!2uVqAL4GilEgR!%R{ z$IvH<%iVGme-myXhCdDtH1d+Fs>+@azK_%EV#9Uqt&X>Huo!9ooiBDr>8LC9=up;2RH7f~Z0?ch0DOQ^46AC$TlthvSkFZB04G;hLg^1{0Ox1Z~i{ z&X2Y>ljR|Ybq--zXE2zgr%;G(zseHIywtgU1w~IQYmmGWcM%`uiz)9(kfd}cq`y&) zMl8OB1-fiLGwTXy&czec-35NZLSLeU$Tz5YhKYMiNsfHDqIwvrZdJ76Sq#OM zjNqne$n%skO7fx){iH=Uf(iU8gEQ=?=`KhC;Kd3u!Ss!Whxs`Xq#A<4r=*Kv%-RPU zQ~)5+%*t8IffCe|h{no5C~Qw;m+p#1Afj1nefnz=>^8Iip@~fnlVjV~&y?{Myy1l> z{UhPZdSVjl)rC)s)5=>2Gb#$|>4X(|;O%;tGsHAaaWJG)t{Cz>!3{@?{#jqMxRRv!ukx@|%%)rp@fLw^+@Fm%S2` zxjv^M1J2czdh;d5K$X-MMF%%rf)7|@^H)~}=rq;qTPsOu6?~dXN3|*@B=ciZc40|( zbXgaBu#^xW#wTe8!jy#4Sf$jB7I?Ih(^T72t1g|r+JImKuO>4+JFU?N|bz##5$ zO|WcWkb>FK`jA_L{|sd#V>z5+>GXzeX6aAE*uy!VFp=Zj;6fL;(_J>RkXyWFKdU+# zhYtTGg=;NjAUB1>l}<9M8(fkP=h@1!ZZWARY-0pF7|}i!u&Cku=3Q6V)v8{`V!$Y3 zJPWzPWnOcIvHWO>Mf<{oNwces?C3ui8OEI+u(Gk8<#s0;+Jq+bjI*q3Qe)Y~$1bs= zRo&unRruK}elm%Voosy9Sli*QpN)l0;0x;*$j4sHqC+gv#X z_H(11S!`b?yTt~!@R5~0VSCp(&HcW$eoL(7Mh9EOJ@&VmzdUbD=eW_jrm&JF9&0wg zIKm|Nbe#tsXOTxE#7Cw&f{pEGqJui$+tx6wx9x2GE{4}n2Xo8`EpZ^9+QRo{F+~4D ztn8Ra+`<6}i+}MRC;;3*3^%wz7;tcd7=(fEG3YxE!XN{`_q{ZPXZ+s{?{~s)0r7}e zJm3irc)!a4^Eiln=WoDy%WIwsd^dgHHD4OW#~|=GsJ!MKA9>WjzVfCgz3V%_1->Ib z^tk7J>1iK^!Mon~fTw&IN`HFOdw%r*n0@Cn&wS#SzVW}uedq~K{mAoP^?&C*4k*8T z;}`z%u|ItH1E2WuTOa(&7yaYI-*@u!UGut!zW5dY{L2r%_QF3r=KoFx4zKsTukTn7 z^8|439xni)5AhDL@^o+YMlbNR@B9Mq@yd_$3XlCjukT7v{a#P@ypR7-RxT<`#IfckFG`(V%SRL}#JPx?g9@oX;$Ew2ZMF!r*~1ThZ> zt55TIuLSR}1Z}VKB98?Lul9WK@g~spOb-Vk(Djb53vn<11W*1jaQLJT{!q~Wd~g1= zFb7NH^d2w_fiL#H@b&Ny05k6d5l{%@kPSahJ5@bQ?? z^e8X<6c6`4FZh%%@%#<~IS~-~PzCXD5gU*Vm(L2xFb8?B_XaTVKJNtQ&;DY-2)A$Y z=1&6^5f0066HPD(s}K*xzzQ#r1TC@ra4{COa1?3q_BfCRr%(vFPz?W4kND zv54=)ARDz22ec6zp)nh|Q5zX=8^tjj0nZ%EF&)z}9K(Pd#W5VUu^r=44B&Ad>(L$Q zQ5@w_AItF^!EqnIu^ajE9{2Ga{Sh1kQXFHz`S=kZ$*~>lu^<~VAh~fL2{IiaG9fWi z9m^5%1X3R>G9Ljl9`BJJk%HO z5-IWVD5)|kQF0!wavVnzEj#ilB@!sLvL9P=B&Sj*sd6pNaw-2oavdG=AK#H8bCM(1 zQZOeHBD0bw(J~}E@+Bj3Eb(zLwNf4r5+ED%D;JY3fATHak}>5nE#vYpVX`c(GAucg zFCUT}J@Ya@Gc+R-H9IpQ!|^C>@*b(t8f{Z70N~bcb2oXjH+}Og(%=Sub2y2!IQ=U( zjWaowb2*u_Ii2%4p))$Ab2_QBI<0d#Yx6qG;%>CFJH2x(B*8Skb3CsTImz=p(K9{O zb3NI!J>By?;q!_BEIrLLKJ7E_&_F!zb3glwJNffJ0W?4bbU+ETKn*nS+JZib;XoO5 zEYd(f8}vZyGeRk}LM`+{F*HLpR8X?>J12BQ?=w6>6hK4$b3{$_L{T(FRdhv*vqQbJ zL|Jq_(cl1L)IC46MsYMpb#zC0ltEVjP|)*6d-OUd0YZngJB9Q}m2^p&v`L-xH(k{f zNpJCpQFi8DXR)H%oWOx1Kv*|bdqG)&8L7~Hft zMRZPyQ%mhMPxW+9`4l>Tls>1lPpk1k1$8&mv``T>Q5AJj(E?7blUf+nzsxjJ`*T4l z^-?i4Q|;7ItMgDb6)o!YQ|ZQ2MYU8-^;A=oQ?t}kQFSe5v{gBjRbh2jX|+}x^iP8{ zP;FH#igZ`8NLPI|ScP?1$5U0O6Hj;5N{JOWWp!Dd^;w}+IgM31NflKml~}7aTD5gs zxz%of!}L4>AQ_f5REHH=yY*brHC@jFSHTrnZIw`$HCxqnUg@=5zm+^8l~}K}T${CC z{qQgL&9zq3fJWoBUl+DwEjClx6<-OKRt+{-5%yw1 zHe}nhVWIP3X?0%@mSRPAWm(ouN%lEE_EX^%TQ|04ZT4od^kvahPKi|#t`u8U7H5Ta zXq7Z$2R1ot7A;<4rjqt7mR3Dywp^RG8mG1_o_0N}_AIh?EVhhmDhf*8;?Y?an5&NgjpmTh&`IZ@VQ-BvBg&TP?E!8|Q!#e#0{jy`3QrU1YI zxK?e|B5u3(YaRDX>y|mQH4|cBAy*&<@>VTw0By$t4bXOQ&mt2(cP%z|1pr_L(10w$ z0Bvv0bK!It+EzU~)>kJt1`ObIF}H5w)q5 zP=Qxkrxtn9c6vcqP#9M%kT-SHLK%8Dbf@=wlXo9>7kklG4Ag>qpI12})>%!KETs2) zwUo&ack>o~V~SM}S1hiVDlAwnG@*OXb9Q%?R9*K5u%n zhOhH(Y4?T&ID7+_iIbR6(6@SvbB5~%ZH<&rR3MB8eE z(Lh%>*Nd0fER+Ea_LnM1m@HhEfcsY&`c)YuAq@ZpeR*~)pn(_!nSZS_Y7f?qolj8q zx0B(PjTPA}h`|je0Z_~sEfiVLCP9$NLXX{5e^*&nCmDlN|Cub5p_Ey9J9Ahqh#?aM zc}me(iFMVL#W#SJ*q0{(j^%inH9Wp#dkcS_9}0Jxbgz`}LWIF!sejpO!v zZ;fujS3D`Vn(sB3m3E$6cpn15n330(!ME?wwu-;vpqY82cT|C2v}p%=d#AVXrdKy{ zAdK&MEC#wXzBhxZ7cD0E)}mN9SNeU&cATd-8*kT{B{hv{7o^eF0A6`|4NrPm)t>uS zrE~gyGZ&4^7kMkUe7D(sg*O|gSHTSWd(C%>%GaXV{}^qMs&l-IL z^#<-0eO3E^v8Xn`b&bQftU-HlwfT72_;(F^u8I3X>)JQ7^?hT&(!4o4`}o$7+B~1T zl@pt~TRNPR`mif|x*xlD51FEm`-*xsUaMBQ`MCg2l#oN&w3$MK&`!4u|4gZbvdky1v|l;8H@irHM7Tp7|i*mT{lpL8?Ro5Kj8<5|I}JVHHMO6#T`q_>OB zf~$e_g#-K6Zg<10+lQwYNI#gp(b~2PJVD*Mnhjh!P1sgr_ItVf#(OuqZ>_#}yv#Ft zviE_=Q(A-Je6jl+Pbs;YYa7r>T&s0iKNnJB=>cuiz{vx+feRe~0-(w{okGK#H;ouA zkQY#pH&CGgf3LZ+7t%;^d{ELEv@I;qMSRW4Jf{Dq7X|_#25{YW-*`GNo6a5FEJod} z0U2#2!ME|=OTo5&SgCbfN&1^CFt!koXgc*labqan_f zI(Y}$c2|8N8NAco-9A6vP~jMTg)^KIL#GxH5ihL|aIOF}(;(eEd!KLON%+hITgS6F>}S7MqTDNfm&F3(@0D(E4S6wIl)1jLhrYHy+$^qk=z;XV0if(xJFq(#@53IM z-TwC3Gv060h=2D6k~yJm8>$sKog+Eb>yvtKS)ETC4VHMIpB@018^hf?nGu^BO?U4U zS$`LjI)5GMxfs)ZU;ABOCWn7|j~eO?efk+$`EgjsnLXJXdz-W0b02!JVR`7q6S2V_ zEm+u;0U`zf0Q(B67+7%M4TJ?V4Fvx{OqrO60O}Q-G;l>GWf3Q4DyZyX!jU9Pnmmaz zrOK5oTe^G+Gp5X$G;7+ti8H6pojiN`{HYVbN1#0cC}Sy*;y@fElPV=Pa$&`b1CN4K z3IJo)lUlJtODNTV@_h*Hm=;cJB=d63IJ|GwGYV_48w4rL%R*J zN*Xu`XY_NxxO6aA+#s%N8vbCygv(7#XZIhM4X>7DRC2DP3y=Kd8 zx88os6S1~_3GPm+mYWl^=&s9dyXcC`-F_dA_^)-_Rx`;r7jAaql20D&+O`T#@X#U~PI>2^W4d^4VkeyU+mU~cdg`8r zP8(s-=u^;m`b4u2?61dO(CoGEbNfEB({4NLzUK}+@52ASd+*2xk9+OKD^Gm#$4Afn z@Xkx$yzbR6Z+!O8PoKLHZ22!$A#AOc9*vCW~Qj&9w zBp)3K$u=_5j(B|J9`zVVM^bW>bnIgr+b9tOaHNf){G=rl`N~*c@|A&Xr7T@J%SmeT zk-UWEEN{ulVAgVydHf|Ghl$H%(lU>CY$hl^b4phNGm^@TB{lhIO>ADXn#NRSH@E4= zY)Vs`*!-qB!+B0{a&w&MY^OTe>CRtT6P*9$bf-AqSA}^xW_7AoW$RwCdQ_pl6{_Z8%TbCtRjD>Lu65NZTX*_c#SZk}TDz7OwWG!VtZNs0Q>0QBWFO%wY}rcGrasoSJEiPy zbqia~{&uv!4Q_9bJ6q)56tbIbD{gt~TjeHqy0*n^a$DQn>fV;Q*JW;Nbt~QFb~mod z{jPI!Yu)TVSG&7q?`_cw-{+#2tm&2SaOoRg@8;LOz&$U2*L&Ulf|tD1EpT=XOknXI zcewqfFLxD8T=h10zUhrFc>%260Yf;x9JX(1DcoWGVmQLs6>fh)?BDrHw!^-zW~dhBB#<2A@crpGdT4CEjiImpWx@{xsn$V67g zkeTe`CRcgMczyDZvrOeGhndJpR z%4N=TpYx1oDZd%WeNJ+h@yul`FIgFT4sxNxY-mQiInP6$GMpJ*X-p%z%7o_hn1f8) zKW|#hW$rYfNlj))iy6>K7WJuD4Qo`Z+Rw56v#Vo`>sQZu)TUl_sePSlPvhFvy$-gq zb3N)~%X-+z2KKCPee7Zj+u5*|HnWl4>RmUx+S|6awv(OhWb?Y#Zg5RM{LQL1@}b|HX}khi&=$8ioO?XvIww2R!L~HL>5XzYTRP(3PPmol z%2aBn^8Ye&1+-Og=R!`<6z*LK_SefM=cz1Qj1_uktL@37nZ z=`i2-*QxzzS}VTmiEldK2`_KK%N_At*SfC3j(4~BSj#PsGG0MOB2#@y(pP5rr77KV zjI)`_M}|1*D?jd^vwZVk9{K4dj(h)!mtM>ThxMVSykv?4I?b8x`H#mG=+|>T;ZLr6 z-QV2&+_RnaL)ZPCMGofP{~F;7FY?7N9elj@KK6XpHs^<)Q=uH*)9XL=*5hvVcqcya z_a1w`H~sFHV>{RHFM8ko9)Ht!dG&^Q^oMWP#&7&5b?`@k19*T~SAdgeb?v8k`*(l- zcY%D@Z?Z;#j#q(87k?j!f6;bt448lJw}Jl$fZ#@gB{+h12ZMpt}z47=?$&h>Q4m_Sb-o_-m5rh_u#-1Bi%^h=Pm9i2`Vb=ca0t z=!l{?ipu7AlxTRR7>Wu=iZA$rnAd)-7=@2#iIvELg1Ctu=zuL4i@4ZqsCa>u_Rs$Yxs>m$Z!7)Cx=NFj4#J@`nQ1==z^wrfE{UoAi01WNs=Ksc-{tkDu{pz zD0lS8ejV9=8X1C{IC$Ckku1rFCCP1nCzJN(fuIa)sev~+ zgA5sQw6|$JBqx~wRw%c8OtxrJiF!4sXyBK7=jViMn0t#hb5dr923Ln|$c8aDZr$gG zD~FIHmuPWGWo5PxhXGY+wrOuTbJoa~mxh(|cxj>KfSG8GXgOs$2WVm`eyewLBWRa+ z$Z}>GeQ9=w=0}#aC4;VLh=`eswK#&A*py9~b+ZVAKUskt$buTEngi*Jr-+Q5Ig6kP ziYS?O5~z2gnR)-qD1y(2is{Ca&iH{@=$lIScXx-HJjscpX>Ne0nx@H;!?}v6S)9JO znxd(QuGyT{sfZ0&o3xp2x)_tQNqTPRhZL!3kXdF|wvAm95j&@4*f(bM`GaY;ejbNq ztM{1S_Hlnnaxxcx_9>u{nS8hhk$BdRVEL7O`E2=^kU=I?a(8H%31*E}RFSEWNm!j1 zcxDsFp-APJ@%WD$N093Hb3}(_JvO1X7j@@X4>dJ{OjVORRdnChR=Sp>K9-}m)>e=9 zqde+pJ4&6LMx?ZOYWmoW%SC^p2$Ut+V>GIQ^QNR%=Vw7`qckaM`Y5E>*`rK)c0q=v zs&=HzCXN3`NqJgIq&te8NGhiDCuU!|kzGfl@@S+%S)Ghnry=;IY#Nkhx0@!oi&1)` zf7+ptD0O2>sHEnnbjPMswxi{@g=HmVJtb*X#b`A8o^Zlrx+j)qR#bg&3L$ z3!8)|ji7mythtk9dW^dGV{*Eutm&{#b$F(FsQ-$KQA(Ui7PJP7i7V)ge|C+D=5U_s zpd6ZH2$_%}st*AWdW1p@w_0U7g;$R%rgCO_m^q;iyQ^eLWNqbBJ4&v^r)h4>q+RM` zEqZ!m`(*X%Ws%Bx^Ln9eD`jk&p>hbONQQj3_l@GVx1UypS%z0S)o_t|fFkO+40?Kd zdzNlSu9quk5~`uAs-n<`YS(CHqjrOuz_xA6x;@K>4y#~;Xs~-)x3x=XOuKAf3U&Xm zJEZ6LR-0C)qUNh{+PbY)r+v1j#Y?6$*}A?~r?hK;uEx8xn`FbgveOA`Y&x|2)}wy9 z58CLwLz=y&X1KiDvfb9D`PZ^RYqthSvG7KF*_x$Q#=GgNZA9yPLK$m)N|dLzr-Ylm z;`^`x{E63Fwif%QCD>!pfK>;4hrG+A;kvjEs)d>sqcgQJomy6$M`+8i4|rI6`;eB+ zC&G+Y5NJk)u1AG;2@Oy&2{)h#G>C;-NS5f?hmZ+`nijQ*X}XaKaS(ZU*q6crT9;{N z9s!__vL}va)}QPe#6j14^NF4-OqVuX!=_7nv^SqnJggKf#8Vix96V?zM`{0QDTd^` zW!`wfP$jy}Sq~PW55&2MIMrmt5CcqsWCbyvlqLo^5RIC5v?4odTsFm0+j^Lw5ipva zwYMZ6@p&MDiqPN=H;@L!D4T&gZ(j$=j@V?;@Erpyn|UgXsaFrf00U{DvQ(FhFL|=9 z8J=Hu8Ze*e1$PO3A*Qcx>%(GQmr`Ts?!$8S@e6j-A zb_pS?ul$OVDeaL1bi{F(PziThy6V}Q3YSH=3-h~rnq zuO_#225_+9CHmH8Xdnh+8)jmF1~g|L7lKzX005xSo}Gt`w`$?YaX{B)BBGD0dugN!j$+1`E(ni?i)`I@(r_4ODV=K;I?}Yt#F$o8LUE7` z300VY12-TBs7#V#8Eftc4T}H(GH}?$JCrWT2mp`<45`=& zc$3q1*)SOmlzjk~-NJcMYoCqS(AH)1ot0ZGhOT-PfWh2}37A`K!=!1evpT7Vrov$9mQ7r8h{mJ+ zxt8X!0&EOFlwFrl)CTgF1nrJQxdr@q)r@E^1+;&&VQ{~2`7kz#pqq^m& z-kyvXo5rPtT&-Wt)<1>`0};bx25}PJv7$_CTneam8)?UjdR{iyQ@xjy=W%WQV}S7k zJ+{{aA-3hH3=Zy%+E;H?+LYNU)c_#Fj27QPjl_AzvI-8os-~^D>7IvSXVQk1|NMCNzu<_cC40855oZp zTMl$ryNCNA5I((Xl8cULh_WvJxB=>puV$&cx0b!m(fAkx^BS^OeY%{k(0&QF7q^7x zn}kuPmI{4)3rekAoT-<7x!kU6b7pGFjASBhWEOdZQ1;sga7qH92J>30Tj>xz&Ji$R z=|`W-Xxu5s05>J2NnFF`tm5iT$U3QH2)i=<% z6@0fxaTxiYsW)$I+Ut|6mZJvOd^xHQF%SS6Jhr(O^;$OEBJT3(8rNx4}T4Tm8Emip>;A?wl#1IWA?y9|aWz&wK z#Jp=0I(v5tt5jyl*7|1X9b43AX>M8ACCqa^{}+)(D08X0XS`409k+VZ{)3Z7$73t1 z9Q&hS1^IG2eozLs3Ma05mV_!>WS(A-&PwV!m-iu##FnbgfvaT6oT(LWsUB?hr)uHE z$g{wRmrs`r1JP*h$)9uv7{ajU744RH|{J!kf?vZv0ts-xdIAVAfoSbY@b5F)@a$>QH0OrS75$4e%3c z#-?$XGMy>4qf5LoIo@MxXAy-a!CMm+6iHAbxfG zns(Z?UGOI{XsS}pr-ee&BCEoDq6Zpc{HtielrV$HsEK+@Nwl|wOX@P`l!4|g>^ih; z!0SAG$s#dg`01wFPV}wA(F*#|xeQ~nZZ#L5(yqUXF4QYH>RJlxrnf}nsHes5q7bv* zrdn+$$P&~}nVNXa2!Kpx+D@r`|AKJM>qV=G`Dh;%3w6V{9^f@Si>5TeF znFd>P@ae;H0u^yahXK`z=67b zq-yY|B*7FZBUATTma}?B$_Z2Fy37h$heAcxLm|x^Qm=iY%Zbp3gi5oossL0KT8*l@ zDA@)BOsc4Bt1~q)Qc-&_usf9$u%3O2m7y#L3j~Tlsyb7+upg-lj$u@n+E-qMK~*qD zqT17GpOr+C%3Po_e5j#N|My|USnRfR$*yG@TIOPoemY3SSQjqPI{pIFhaTbtq9~~3 z2-bLDiz1?@L5gAeG&>jz%Z|TjRPgRRth3gdJOGBVv7#6~%x`Eh(lZH;DxukQ=7)%5 zx}Goqu&F-##Aq$1tLz&p?i?81Clk8u!(msS5L?lwvKPfW?k}G+(a0FH(+e{?!;UdJ zC@1z;$Dz>x0BM3q&5$}ZDq$ zAiFt@GB#y1V=Y4;2GH99OmeJf@PbxCvCjdDu^y#R=mrZ^57;s^khs~$0F5IWY{nvq z73htDIdModhLOG-Xb>vMp%mT5@DrF(sXh$}oZW_o6(^Ep5`kmjPe2B%uw0NJ$jP9Cm}cSVgF*#5q*?RZ#f`cPK0u>(L^I|M=a2!e1erXFw1l5 zNu!EbMWvPLt&9#3%|4PbzcPKqV1)al`U+H^NwnvIaYRt_ypzTt-sFmUlL41VXdf92 zWM=O%mi+_={~!CnAOPuM51Pz=TW(9y7=q(gOBVi205Z6{t@BlJgXiW};5FF4gO+M*o3O_=^8{GAt zk^;aFt`#>G@hOH6wNG3RV3da9AVtqh5JvRzzN!=qi-c`u2#ZD!gmf^k^dSyq?PJqY z5u>7s)mwB>$4WICu_lqoV4?)K+4O9uSb&WoZx|v%G4xM)@9Gdt67>x0MeCKmvw2@ZTPSHeHdBZ6fz zi5hwsw@Ks{zXi&kYwM%Dbd@!5ns^97?^43wyp~2fiL2c(v$8ap#I@4(re^y}67q?c z|ATVt%Rzw4&4Y}1uP|V+L@FxY5{gP&Tva0g@Ten*2#Ul$0e}GloLc*2qD(>=aSS-9 z38|o`vaTJhYUqI;6?0Gw8Vqm@h!X(3%1umlRjjeNV$u!?NIseg4VK_}W;B1t%wQAg zRM^rQB~S2kcp{E^wv!)SMpq!-TpXN20?QxNkAw}>$D7Pp4=VM2$ODxR?y4 zabb)L+dN?tg-BPP10AN9)EuZ?hDei{92`r{QQX)?BR%^xuu3hQmTG1yUnY@sm_i}d zfymGqm7w#X?h^Vt)A1vxK4;FAWB=!0%6 zpc6sm9U$Gz*V1L=aQ1Q#T8wV<07BayW}bCzN(9Kk z00$9K*R|Nuw+%2rftfUJ#4X!HOIfx%-^J_My4L;_Kz;Q4fV8MW(Jh0?sIS^Dnm8eov3)KO05AcK>3oRl#rrv0-xZKG92 z^Me%oz=0w+zp54O(>K;698Yn>BRx(@!(uIpTBmX~<$B-i2r&vqp^ydHkx1j6dQhpb z(KMxU5tqP?B2kjdXc>-*iw86e%>jK;OH!t`W-we zo*DU+6dDaG@{Y++wgS(fvgbgPzyON3ibJkYnSG)MfYJx1*&YTX382^`w;&;9vcsFu2jWnUCn_4B z=qq_cyLjm@vml`!Yk4ic5D5AZki*fPO5CSts0F>r zge2peYeBod7%mwjjw~#;hkJ?-l9qiqFfseS^dKWeK_Xr{~`o0R1y$rOB!=Lk81kNLNIfT2-Ka&SP~8Dj_I37t&u9QkTfMzKUYeFC#w(M zLz8D236mfO!Ke>7IGkuWkbQ%Xa;Yu==$mEGF&t4cN|7^$h?`lN9`So7$so0*>Pc0a zk_#C@k*XY!>KSm_2Tq$t5(Evvur)RlHphXQ7@W$@j4p3N-J8BKEvWYs&C}`*fGs>d8WFB%U6GKZCP;n(ZO10PMi9y*1Yn!)c(T>tI zminoJF-dw7E1x(J3sc5`r)3Z!Nqh>@{2OALE@C1a z8}U0ZalV8jiRUUv)GWkABduZFj{Cs~v?>t9ctgM>FaVe`dLSrcl%+eW3V`&8%2~I4 zf`%n*o?r^M*dr2@pB1)EV0~t z2sD|A1(B`dnT+O$2G$fc=>ZeORI&zg6@qaz{~Ym3r+Extkqq>>8j5^Uu4y68pef`; zAGwJL-ip0RNeS_5P4eSNyirM(vkx)Lo0?3xm3lJIM9sTXfwtH$#GH~B+#Q*6%3jN= z-yqAq*pdh_jFgJ3G871p=!vY9MOh3TqH@aTTZ)&8wbdX%y_hPJ3e*lvROf>nuVAxZ zDa%j;v$Pr+AhZZ9;StE;n0m+rgMx^aX}TdfKZ#SNAhphcF*i_n3sBV-j?sIGFy zmzuv;qKEGp#h<_m^D(W7!4V#5_+f)AybVrv^Tu;)q#B|;y^H`8!%m3iGkRqd*Uwu zc!Qi{Rf&**se7W%BgsFAz|pxv zo@O*Y_DT+G`Vbw&4Krny{4){}a)9_Dr~-|d`q3_d{nfLniA{-(>&ZvUT!F6bst96C znpl||Lzb1GDDH`gsf!J;a<*d0yc%3aJ;e-@2(vqi9JlM$j2&Du<(;z()sR9%Cx!n~ z##J+~X^c`uOgAOOXG=^Zs|bK9Nilo~#({_cvnZEvr9eBv0nrxtL(c8Xn?O2WvQk2$ZzNrxID-HN0EeX#V#qSs2;EZx z05#wW(#e~LOI?5>8U(Xgf}Fx=nA&Gsk{W6Vc$=Im-JUNwh=&`*l}U^b^bo%3Ar~H) zoU{`{R4!*rBxxEk{Q%MG^$_Z;pBX0NX`3jc;7pleh?{t=I{DAOn9Z5dB5}R380lF8 zWRf185|BL-EyCX^4x)+RHKz2<&``A&T-?TOT)k~doU+UL+CIF&sJtwu@hdj}6rS*g*HtQL;?rC5``7i$DWFg}~rp zo7dfD&LGu_=?W*C*T?86VUi2xX~hni-pIjTS@YdVgNY3+ly=^d=xqv%3|FW67n}$( zpk+N6r6tW9EF85Wtnh&^vx)y)la#zF)j84j&{<=AyzsDyGlbh9B8&XAr)~Twt+J(x zg6P3~h`WuvU-maH(gy?`j{}^DvB@BFyP{zF2=hb>TD1&y6*C=tzA`$#kkGGnbrBAo zLKaz>P|}UI5D#?33Xns-0pd&%bcrg-GXQ`C-&tRK%L$eg4-_il2HuUqfTa%VB6{%G zLyMsX`ZF679R-mib^J5DqP%Jr2oX||?{Ve=)fV$fO!bSIBz*tt!V+30AzG!~sV7TX z99E9FA+0X~$NxMMFityD6OpOB+&qK7*k53X1VO#*3zKoonk>3RUq?%^#@ zCN@X23n7IWLHuRASPWpo4lNQ=n>LQj7{T8#UKW9d02qc@uI?tS zsiepyZGnSPppp!%A` zlak)kW-4@y(8adIH8r#BE;ZPPw~EIg29&jV2(gYEgyjF;eVmfKX*MwdD2#ZvcHCT9 z8oq{l*wP(VTDx2_;YSY}QgMHf3tBw^K=um?&A3Z!48V zg;-x6m78QpgGulX(csLV=q?&8h@1?O069Yf3BlmpBa4DD?kIGCR_qgft#&C+ntVlI+P)1w{Eu zL0~Ey%F~H1H4EYh=I!v3n!wR)1iDphKjq}ap&^b*aMNB5T-zO~=QzO%v7Jl%8lBpR z#Jd%MK5+$n3(R@cx%jk=`ZPwZW|a1tXPR z=o(y86PIB0u-FINybpX=G=jm`9AsLVo--WYF~otBo4UfRkg0u4Zl8A;N>W>*114C+ z!~qV>1RolJ`npLWL{7p1qG)=K(6DMU2|ltzM$vDd2=DKCG7Q6ZCNa;87`(%2K2<06OXTkz1)JCFGRCF4INm%AK0CIQLjfW`Xk=^zV44FY9y1ppr?3zNnO;*iEs zQl9M*?~@7Xj~FN$gXsV}C_UYWxN4j<7PpuYA+PVYis-JGutCqLjj-(ziNhHCs$P8< z3+=%Z9L-|v?evLjK^Gj77^TregK--?;x*SP%ps1s>Xe4|m2~7ni*g$Gb)DY}xGE@IOXpBz&AXrb5$u!DRGX2T%X;c6?67E}c^3BeJ z0z{+tV+&)FK;v-(U1wYbNm{2Xuugjp(MH@Kr zK(hrAn~gk|>{qpQ4~E2Cc5&myh|5CjNH6qU$6)VvUQ3st>A55EA`Us$AT$8PD1#-d zZy108nL0+rky0ptNob+@q)9Lu?*J(engqOW=7Fcmww%-y7p73*A@$AF1acW~lw?if z;8`$?&Xp#|B)m<`W{s z3PHRfu#bWO$PiRiZxmJ3FdRPhAVl;ehl5upz9^EFJK|)LCJZH~-BVfsAVx~dn3&UW z$_#_UZ5Hwrl|aiR)7xKFnG{0|P6ahdZ^O+bLqu8uz~OEV?NiS_Ztk;1dWO=2Qx1g% zwiHqa5oab@`{0*`Ktf&hRy0QmM^#h%(38nYF&qRX-;srRh`HY3UeAnC-_G zQ~Z%t4<>;Qgh>FzL<5l+CJoo+nUhHAQF95!Rg#&v4TN8H&=jf+8VD*>W*YkVdeQ+q zrB+XzE(xaPYX#w_3Az7TLPKpmU5-TDTV)Xx6izXuB;KKc7D!f%=K;VUxbcR8BwgEC zHke3|an{g78BtuZ#TDB|7fEl~%45N=J~dOp4(F>SNBAkMRHi%8BeJ+mjj_`{Sq6HN zm}HHWoxmqi8xq8LIi^o#fwi`oYO~=hS+9hZ#u`0h#4r^-fK`TBSCoAwS6j;n?bbn< zg=LmfSHhHUW%=G~*=D&76x!H0hn1FQY0sA1&~+g_R@wIktTAh84=pjd{k=&~OD&CS zCCxN*RhEf~qlqkBrXKzVn3`~e7p51I)+9|1mzUDi654svw+bcNl5oTwu)>2meUv&5 zQ>lIGRtGx|l|;q*?`XiU=9Uunck&S|IA|8?mVxWAcjfC3S_AgJ2_?_s|?gb z!mt8RG?F!vSV1aNRZH=7CI$$on=F>nPNIH1_uD8LTD<ts6u0F3<9>0RW5{}2HgjkbP^F|%w%@V`6*1816It%076g6 z1X{iH6sVo#me|~kJ{)RLkk~0yX6Z=)ytEV*^s`L?K!axX;nAC|;F(Vu#!v%QA8pRe zPULD7PTxdMkTB&9W*LS7#*iB7PL&{}O)cgkb10hKV5+Gi24_?A7z|RTlN!8%thoPE z6){8uJd4WaU1IqbOi2XF5ij9Zoiwda&LEJ6uUM=VsGg+RuPMqOssHg*?b zhLfXqAsR;o00WO@SI%@>UG|LYCqzaw7aK#E|VHgsTgzUP&HJ(UhXieck6S`Lt5!yZ?gRSL; zc!g>tww0##VoXv5XNE3|p-Ide$noS?2=EGtxf79kISkp*&NkD2j5-~U=ET{2Qle*M zlWqI@ve^1eVI~qU3XhmvCT7`?J+hn^v&PlP)3LhoY~xSkOUHvOHN6vU=|{TQ)PpnU zQ{tlImtc$4H#RWD2l+*h{Q4!C=HSX_L-AxISuu;bn~2G&;SS?`!wwl+So((JE3tDk z8{`68oy>jBrenPFn7I@soW=y^Z2l$ipgaHTcwTcN0DMH@ z93t83UnBCuCIhj~bjYP~rl-b^dh+eb8t!(7n_sMcFR%QK$=DnXtUs(xjL)3YL|4h& zD4b-)$MJ7z(|X(EeDrii3!O7x^;_~LOs7E}n|H%-=oyV=wBd#GNEY_uk4{W7b7mRt zz**jZp3S9!`Phq>4Tb6V9h?9K=|+e1V)*R%=Vs42zLZ@;nx6U2$6oTShdyWgPK?z* zKaQ7gdf%5BXR8Zy?Z%W|lUKW% zUilSWphZi^M4j&SMg3h({WZqZ1kqU37(tjs<7^78SW1Ho5ryy`YMkHOa3AlX-{Xbg z=DFY5lvw2zP2}m{)-|0G){}ogmEjNt^g+snt&7Wb9@L#&uRT{FO@_}wm0Gk|BOQ%A z!C$XM#=1lc7ruqmaNIJr8Sh<~0fG&T?VV)kpL4NOS~T6()D2$^;XLh--w9G!c!XuV z1}60()*W6J3Sft*lbgK+%2=HU%7z#2jp!j?BTmo_Obl_^(9-zP{22}4d7mHB#?W}- zGNB*x2o2rXVQSRR-+4&foD|(o_-_SJPrO<>o0bu4; z9XQSn+jt=K)#T*m4F*o$9o=FN+T!gsAv@5zPS*@}?)o`>9>0QzLLiCzktllw7a zoJFIp037iRoi0wL(izQ{`DB0mVMSZAk#Al$*&7I?HdKfXhBB=qPVDchTGM+x3 zU_9*&VT$GJIovARA^lNb0rsRwGG*jxlUe*sGA11%0TiNj)xtauSO7?MM8{mrL@4Cr zBk^F-SmkE2rc>4#^|{jqhNckaUYRXj1-jYbRUH5fL%@{Pn~Z1vy&tQoh0L*C`H7%o z;+SOGg;q{eVFqAjj1%GT;u9`jaIT*YeI`FLCgb_pWccERO=eyy*<@TIW~$>gCg&bX zWl*Y{B%lErOoG9sW)}7z2wvbcrl&5J zRX?WT_7J7k!63!~A;~DHgDM%Fy;B4RWn_w^i}K|T;i6sU;bB%K(<$9cY9H6>9oVH` z5sF14Vqu4jV~rt1Jw8VENuP7cCT;4e#6VqZom(=_!`7z*8BKxzwm zQzEiPY*a}5=};A3X6HK1z*(PK~&&sp6=;vX3U8aVn}Wz0K%Xez6F5hrutc=9xhDhu%AFW4Xv_Y z#-6C|i61+ejr8%J1|HQ*JXydh2FSV2>C6jF>;o7ukEDdkA`)h3rizC&9?mivO%iE; zK+Jrm3eWcJ^nnk6=B+GRUP8s>)c-EwXtr3uaIKJ9>?Q(PosFKZk|biTo}AKN#ir;k zp6uHIWnx6j{Vh{Gp{R1IM%Z560E$Iravoodj!9>}_>G|p-a9-{8G4bQgXFmY|(`f1b^)1?a8+eB1S%F{N*1fFGG z#l8mkSc!GoMDB&72Z9_se#bProA`O5+tl1-itkF!p>qz+?K&^p053AK9nrckSq78% z`eS0Ugu5K=o;rkBI#<@rjr-LhEdJaaMk7eP9e(y~|C$^J_a@oOE*}!=gBovQGOtSw z??Ix0LMkp@SdaF|1OPZtZ~ssVCE8ySK55YDFDq7F%^F}M8e)?EAB~c)*^2D>5~Uh<|{h$79I*(3lOV89^pS;V7b05FqL&F=Xkq!8$NHsc8zs`ine zqdsS6P;k^b903v|R6c2c4)Lc#-GuV2iPr0y`77Z@rSw{0L8>N~60!nc3BY#7H*ugq zmS;>5n2la8WnODGp;*K$T{xzw`cnZ-B}uU2vg z@?EUcM5D_YvF3T+!j@~uLL)E%5>__JJ&_`aZAPl#Wmt46BHm*;A*U*za_%0}8d|cQ zb?aH+Uq64|+_f%Th$Um-Xa?V_nU$5#NN*kfZl#TxY;+Eo3erh~6Po@qMUMusYDQm< z?843x;B9aL!rAlrVlA@h*y!q-Z8SPnVJnvgDe|NvcZkCfuom8?GN$R3s&YxftWkH( zJEa9_Y~U=q9MC4R(*-j|{zVM;ESv_0FLRJtqmvf;Cf!}B1BxivRx8|O@+@2CFOe%? zT%(olpX1I6Z#Y@2JdTI1_KnmAwTa&8oHA*f zhA1RDH1s8O3`-~VIdna|Fru;Yy&%v-{7TFi#L5gzi2mn^k~1QgAVRZx^WmAL?XxEK^rCVf)8gkDoWj9}SH)U?N`e zK3-CT=+?0%^rbccy5#V2=G4(Ne;!^>g3l|S4H;kJMVI$k{8G9WBZjk0NDDCvDjpX8 zEj}F~fd4xkJ6Wr`LTjKYonv)b76YVHq8@BEYfwWkb3Zt5@+=xYB2_&$WG|rM4JqY$ z@#QIN20sRyu6TeOb)VWEh2k~%nY4Dp5QgD+8G0-;)!e3}t-A&lb|A>*{LaVt#1ACs zYKeI-+v+Goy3TJ-7Vwg5gI2mUgOZ9uKB(9jZ1A1 zwx^R`vp3)96yq~WeytQErZp2?iX+v<5~j3%w=H1^n*s%M7#<8k|E2{Ng%k~5A0bd!?}J?fCs+!0qFBgDe@ zNB_gJ{rxxhYB%}rrswLAaa(lJ{CPeutLfRQx_-AKv*-pd#~X?nqI#e|H!zeV?G#ot z;Juywy0!S(UKn2aEWug$uC-N4C>}mCTXWuw5U3+El#2K=SqU_m{qTE6Hc6XyWU#CtMxFKqMbMpCWQo7}ucB;3iyI;43ZVFVc=uWPB zxSP83k($ggyaXmSBMmaw-n-2bbX;I9;h9(Ix*e8L7&t#A_*7!RO84Iod0@}`UH?NU z+U&DF?(M^F7& zcr?m(5CQ8}<`5BC=S<8;ju03dUhn;cA z`Dx`YdTlm--%Yd4L`xkr0fe%8%9PPtMvtJfWeF8BTu2Zh!GRGYDvKtuAVFvdA3mf9 z4PwZJ2ss)gIFez+g&q@r9QaURMu;pMIxM)-W=okI84iR7^QAtP%YGItnxt@`zK}8} zE{$2SA-#(c2g+1vGA6@|Ss7mKnUP|{jWBhhJeiPY#+3#uR;7BfB2=j}k)q|9)nrqg zD&sbM8I|nNvwOYDt$P?F*{)I1;vKngEXKwe_npN`wjRi;2W#GyxUs8JgV6qhWDHg2 zGNn;X4{WMdXGNSSVIq8KlBdd$Rjp2zOx82+j=tfZ6)8C*Z;>Pmi;cMtK&E}usaLmt z9ee+F?c23S=Pg@z&6_$&Yes&2yuN5*IS;?fTp4MmsglQ?UL zDDb*!DmQ}m5yJrG7#nb*eP93}1_09FX`e6vxPiibu!`?H<46+B!35=#%t6IYYiu)( z=*nm-#>BI&IS7ri>Y=GD3W+U`9)gY-@)BB4Jg0g?2{hDhV@RmVYO*i6%BreNse{tO z=&j`FvT`w^I8)9&+7h#jIJ3rN?k>eXyvoO#?pyOFghcz#Eal)!X+{8B^vgLnxgxN) zBG&>?pr2?|tE8_S`misyWE>Dp=dR=mC;CbY(M*Nj@)w1H5Y(k?o*~Rgore%9_q$ZO^g^cNob#F^w~77 zVPZ%l*kkbo^g|n&Rh1!-fa5Q<)m&`uDL0ujGcKCi>uMy0rK;CSw~}RSpG5!|`Chdo z85saLtQ~O2g;uM|w6t!6iQ%r^f|l1!Gp%ploE#lk+cFzt2{j14B`8MKqO0s7UQ=2R zr~Zx`Fq-L5^Ji$I;sOn;EKhHY$WZ@ow_>R( z2dgaFs5@I)7tr|-`)ehoS~R?-5|IPVW9252)~l+7%4oHVnkIBu6Y*O1;=ppk`Xt67 z+A3%Sx&513J~71-Y4+T{*|GS}QrM|IWj}~kqA33sOqX6QXsc$QJNoK9~Ob z&jmmehe3^ym`rX^0SB1?AG<1)0}n+*WH^wLRR$7`OaLGNP6Cwf7*@EqS%!9=g5Q8P zLl1I0j~gTK4I z>SqP255u%2!K1JZZB|krTtG#j%iN_(uHwk_W`aV9(d;QI;-Z35rMtdNaZz^pmJMOH z$eOUQEHwmE4QV8%NdmH3C=m*c@)*g1@d#tva-2=BrY+taMUkR(UPqePK1wxlQ?7zg zTd3$cr)jECufk+zUSyc%4Qf=1M4M$iC#n$=vmp*MPGTrRq|3qWlOL2_h=#_q2VKo8 z8C(unOvocI6^wdIu@z-(5;W*Y$A0Nl=XKJBl9JTvfha?nCglHAp)?rI03(xNftrSi z4VeXQzFf-}X1%CL;w-mRLDw%}#}%HbrblCfUapMy9O63`3uN ze9A^f7K&Pt>`=8r&PZPcIj$H6cUV~#OE<|dt1@a>Hr(Q;M&p^hcuPl|sp2bT=faa} zv^XqNt9Z0^sBaPPH+hNMVqTM`uAq{2BeJGk>KH1Nuq{}7F^i5$g}TYH40HLprS)oZ zB0~y|r=02LAb)q2t+K8$@1fli-Ra0l=Jb;m6OBy0lE?r2z-cUVu`7M_>Z%@cN~5s_ z%rd*zQb!$ZMm2*LlKw*hVj-R0tk1}5d80{PEaAkQbFLG*>x|AE57b2pX`+7`QiGH< zl!gXMA_ik%+S?v@fbl9Mj~#&$YJB&_xrS%1XK|8A%;PLywlIhc7e)fPGVR z)I!#i){1OWSOHsRun>znxw*!KT(VPXU;ESC&?IlK8fS8~RH^nP5p(rfT3v{?$^|cl zBmTm{fLTKi83F)UIVq}wNS4FmE~T_z3g?S1R>KcN#cGz=9sR&T{2aMC-Sc02lrcIcWOCOln%4;8FhFCOIJ(glSVKD~n>|EY zg6(Zaau-U7M8-&hC8eljbjB>Tk3CspmWn`l(%)uG)DfCrbZLD*Vw4$03er#v_A!=y z3?pqsO+)VXq0ELZBN``@!D?B#liD0Md0h@1wtzVq!&G^Wg8h+09QMX9k6L-r!01(m z7`kZEEWldv;5Abf$W9Zd-Q9B5wk#~3G+z#=ek*P((GxCY)?>QL>xg_X9V^w;3?|T+ zjv_}zjFAN|LU?KFQ=xdecWSJq)lFTejHI0DwTaUIJM$z$jsj%*F3DFnYjzE5QpB|A z#x3|3vQbGM$cR=j$ij*0vlf-+4uWwg72A2@9C@djc}&zvMlr@?xh|#mh(1NUZzZ?2 zOrY>^iK*mmkV$f)3mT^?jD5M3|9n$Fo%*Nl%+b{FG$>{AoY;9l0^g)B6<1tJ9MRyF~-O6 zoZ7xJW9dvqhdLV5)6jH@3u$gcx*;Vh!}wzV$Ua`I**|$`#_S@QPNK1ymmxCy=V9BZ z779At%8e&%t1B{5yuXLx>aKRa;8;mz(j#lcd&0`Moae4;j?;Fj?aa)PbO&{|>gB+W zMYd(Q?5*c&YlL9uI4*3jNJUI~%x64{D+mpgv~KSR2DeJ@t^8)yKMug{w zd@MFjCx~)FYI*~#4#j0`OWzc1O#n@TEXr2|P;d(Er0@O$Ei zF1QD>Qe*?0O~;DqRq6qw?hx;O=Cm;X$rBp&K&7r+hVk;Kk#Hl6VsB&ufL+RPWMtr7q5-M6<~bxm1>7)<0KjtC1*uR*fhJD; z@aM4>M4n<`fZ(WYc1WRIDNw{DD;|q4_(*niPgsI!n>gr%M#_cg=9#XflLo~n{-TpY z1nDYBgm`dBdTJ7<#dZ!tM+{{4)KO6cgNgVEvI?#KFpvPt$D}r@EOyU*^5g=sM2%R@ z_dv(efaw2x>!)Pmv!Vv?5(-oj1)##JO#+bQ>cj*S?lO2T%-l~J=}?vwjH0A$2t6%* zFp@6zr1B2Q(B7or+%IB~g;+}eOZ?EO3Tu)&rfZh&4U4w09`xrbx~o<+LEO-zj*s@D1x#Awf@afVAPV$OOegjv3eByhaOYWy zsPfWsGBQjbH7ZhK!ggl=FdVO^SSlh$-UIhYO(*OF!B|ZrAO+$O#%u;i_$uhxCNC5UOm*&aCVxzV;@+qVY%)bOmjYNx0%}{3=rJf{bR( zCTmhKW2P^@#3=En9=2>B>}e`AgbV9oCr#5s+7K2$ie&a7UX+1k%FNOt)GENqD3}a( zxQAW7Onn^jM%t{$+@-eI0-;_5DbT>Y{w`M(OZAwjQiwBQfaBYQYhbMLb0})bq~dxg zi^1lTRX&ITS7iQLNFd`18b<669c2~)K)fo$45x!B$EYC6D@H~}f#QWSWe+0kbUNw* z4N%6ZdhuSCVW>)?(P}g#N%2cI^AkW14$*K4Fy15I-V(0BML&w@v*x3qsEDrwCDg2M zd4h&68wyKr=ZGi;FB(#|$Rtb)(%@JuPt@`yuT;+9BZy?P9tCN%T*PTwrH&R+qNMBt zO|?>+&}$g7{`x2(t7xSlOX=eC2kS&Y3G_5P&p~)gKX zO|i7i0d>%ZurA1o(75QzLNEW63ZvtyPE0~jCIH4ICZK_+(4c`B0RS9;N-AV1@r9_8 zvcRroq)%-KaZAwT*$T921QU#`!WBp64HuSVR^wjpNg=Q(2FU1S z98=f4NFXp%f=m%#inbu2wrZgWI#sr3MnyoJu`8#=Np#d<31rQbj?i$W)p};5FcGf) zGE~GFRo8QYQ~%tLWt<65!~ zCf@Evpe6}_i{sX$HwphGBfnBA2ejLk4upmg(NoG+K z%p)4GNCs$S7OSQ@aXr5KKAqQN_OjwWg`M(V+z67?W7WDG9C zg0pBUCPci7~s4u+sYIV#{}gLDQ?Xz)_e+- zNFs->RhODmQcM2~vCG8ROpjb*yYVS7i`XcBo9FFFv1ig$whRJ1Y*^+GHH zU~ym~#OOQ9YZ)>FUs2`&PzI6$%K75+#AfR_ee(qq6fw{jZ4zXed?F3X(pZ&h$pF)n ztgXlJW|4rC$k@~1AdtNV?NlW-J$DE?s}3dp_bjgLGEi7u(1Ut%aVd~0f;giLQCT67 z>Hu70LWcj=U2>6(-r0?@R)tL&Whx{9R3HF^w)5_*$JWaSg-Lip=UU&kWA$`q@^V*5*g(SnR~BsP4HDsj*w)^%P5d*5e6%g29U#3iUY-4+eS&l6nL0J zhM~A?LJMmwkN|;-r`A&RdM7@FwMHY&Ih8S0HxzD4PSgtVFdi~MhN)e7rZ3>Ab9W}w z!~#9ZRVqo39)oCutZgvv_@~eKNvNz{t;dP9PW;AYljn6XS?r9S2_dbJE?V96pzLXf|1gl)?lV}is`hSC5|I`AYvKw=hC)1RDH zASwh6+U0>@Q5j}YWuhV%*W+kAsTM)OAW+yB>wz-+d9R~807B|_Z||6G2r8rnO7)L$ zkp*wb&L0uUnxQ37D)?kCmO07FN{p?@a&82t0?698vG%97X^A+|(>|qiO}0!N6-h?@ z=ryj@^Io@#JtK#vhb;^4do(x690yn5){J3;&@wVwW0$}p3S6@6!1`-8L!x{O1$l(H zn*VOoQf(!2b3yB799NEWO%l+sGMck;JapIM)Wj_R1T}GYbkZfQ=QR`hW8e(YE6V@q z4F&=zr9xx`_G&$}C0@~GZaX_tP>uTPnNn|%?j!m*9p7 z0FTEe!#vbvRmc`FlZB686qprIF@ z_i4poB_OjtDx}D}0&0)8uk3mJ?wZ%I!#;NRyvhf=2MVH3D@5oEne>rp^c$EsgM$b8 zSj9pwgr@|BwZzdVzEaml?{GZLx&`@Wk$fUK#zLFA89pIuQe}2`mCTP_>GjAnZ8%V@ z?lF}}?lh_R56i~*oP%FVY)JzK5aCXC1FhD3ujlg4mXl`*TLfh{Q5YZzap>RgRvq>q7582a6i*UB~$n2C$ z#NpHKxH_>CY{~>C8>u3UW}BrSV#fF*w-;z1zVHW>Vjm{qdFx?9xR5QtmxKd0kJdw# z1@$8mJpf`luDS|astiwf!(rg$buMS2$2<2Hrp(XC*>xEC#@+?l4wF1xz$4;s|0MfJ z)hmHwSEG~P{?V+}sKHMRlj08O>|A%D?WKwp$0u2jC0eo~16h;Lw!HsuXZ|B21M+kR z@`SEWqW)GT*PL&9SS@ZAtVDY}(|hN`!bodxT7Hb>_-=L;N2m?AO9Qu7V@3Pt zrt{InxwJ7yS~5fTx9(@Plu&-;zvfGIai@~!&JP8!xYkegKuvSU6(E!eq^E3|KxOp` z3QS1PAi;wUml0g1@8Cd-%b+PE$WWlcga-*eG)U3l#*+~}UR0=3***Z89v)1n&!Mt; z007ujHVi<3eFvk30U##fGGPE>7>p*#XFY?^_Ql9a5))OR^!EP^1#s{sOoRGzY62Q@ zpG;+$K%Q*L@uJa?CRrlfxU-=}mUhoh)F=_+z?5?P#$C%+p~=H{3${fpk)+*=B2PZf zc(*a!h0tU|14&RLVX$-iUdB7OC0&b=MJtqT;kaw@OX*X`_vpY+hmWf#VZ{^!jqCBf{qH*1SLmJkM-J?d3 zB>mDWFZX=Gii2@yCO%mF>GZ4#M4xFU5fn{iy)h@ANw8)2U4Z<#1VASHRA}La7-p#9 zh8%Xt;e^o)ch){V0WiryV&s$qQ2W3DKpH^RGZYR$@s$4)jcDbRREPxSB!f#p4RgaJ zJW5AcYZC$2l1cmB_up&NDHNh*)%m3mXErhTUuE=!SQY z=GU2((Pf-yN$!N3fQX?PXK`9$WTk+LA%@_R{sm{IO!Z878+cYy1&u-bG<5)02yFpC z4i(jt2>_Fxlv4xr)Kg+k2X2(p0mMWzj0!r20;X8dxFb|fnJiPGGLp#fXpaEk*r#{W zc^TWDlu@^wO7-wX*sjU7wpML&UfGp;NR|ehXZ9`EWs*`-tDI_Xa`zoe@O^eysop~M zpmix_86|Xe$yL)q^Tr91aDTn`n|Yztr`=@A=$ro-z;Z<>QHbTnCYoghJ*uEe2o_7+ zw=1d1r)jhG=TdscCO4aQAmJz7VR;Q!U`AEKOB+U2>KWjC3Wl3ecYi&kZ+xsl3LU-u zq3oDKwG|hz$$`GvR=VRlY}9iNIjq-96nZH2)KpJB;dA63G?k7z;_#3@Q>7u0Rsc9) zmP=dd7(h=4^rb4-T*JZbTO{{99>kFSY;j;G1^sT#$BtH`diN&wUo>c}P$RegdDop_ z2HUrkT}>{|=)Q5bRH~tV#>+Co$xYXm-=%)MvSAaSC>v%sIc-E+|1>tZVtHn@vM{* z>R4{D)GW~zP%kb_7~NE|Id;iTBoZba%4br!D018xTV5;BryDP z7UTA{6G0JCS_&cG`lwgLN)D%J0mNkaBs7fpIPM@}P)bOK5d$1CL=pkWgn)P{hRi@J z6PD_gt#XO3Wh5h+I6zwrN+p#TfC7e@*ct$a#YGY4$^%FKu zBvhcFNKVKZQFbOJ&nvMuJHR2i2BH8XNWGNvF*+sYPMRFouYe;?0EKg&q={c&pq9n1 z|9VwJ6B^uGI*B3s)MI+K8r(!KG`0|S+@SgrK(l7@u9-AoZ5p@|kd#n>)B}vV zRL7lijxBLw9hp>DvKcM`a(hBt6wHoQQrAWBMj^3a23x zvM0OFb1TcF^<1rONQJV)Rv=}qwzGZfmeR^r(O8J3qr4n|DoNbXaZ-B~M5kk13Au!! zbd^FZsZSC08&2BKAzs3oDG78>(0W!m)V-TR*CH%(`j0fc38MMZr}vRE@%mbufxJ`j}DuDHnqFcbeH$X|l6<2{=b%($GZ})mnn&=T~cD7N?N7>!nn=CN>tQv z%j5?0BXxZy}(uayFX9p!#x?At2^ta=kxA3ILR9 zZ&6dq-#|x|O&%=t1y$op-(cE2^x;-XT-Rjtuy4bJRFcC6?84ks8+@(_OD)GI;#rQ@ zx^x1x${`KuDes42g}W1jJab}l3j|sr9Zd@$zlJT}p0*(-G<4MS~pP ztEv;Cp{w@QlN-vNaqgv?EvhZgO!hXDT{urKlWCB9tR6>6+5au&|IijHk&0FfTAKau zt0y17k`V@{E$PVi99cc#WZF3stFNxXTV~CWyDiuf*1DU@Eb&~N&QOY2Rs~3z-|Uq* z0L=VHVdJGHLqw0}D!gxMuN>6}6wSloYQL8+wJmOt?4fzIg3ejeI*qqM!Ec;EK=&NT zb*7Tp9il{|>pvt8?JT$N=aL4+>ClKF24o_2n!f|~g|+Xz(5(-{vUB%s^|^8GGCv7I zXuI)wnPz!fLSyx_Gy2wIG6PV1rzF^?B%kC%h*li~MSvA2KgaA(?j8k z@qnq*Fh|%qLPQ!5*J0EbPvSFIb5lX0rFmR(SM$b4ts`fv#zC64W)iY*%$JB6qA2Av zXNhK7uE$C(r!9;2XMOcB6laC-MMr>gI|?OQ`&C-I7FgXUZHHw5Vswzh+(o zcz6-Ce{%)l!HyjMdjOpvYxGbP>wZ z8V9pucLE>lXc>CeaYMLbE7Thq<|ZlhD}rcA|1pJh^CMV~6kb6nl-MSP(f2E0`G3#m zWW(WZj~R#FVVYD09>&BPp!1c-R%We7m`EdL0p=k5C39gIT9P)4Z1_=ESp)98(PGa9Frms6%2OwxEA2zFiRg%BxP%CQfL^OX0|F7tsP zPp4EvD|9BK#Q-I-R62P|`SHnsmwlS`BPY*Uo zBiERIfq6Y?GZm;^O{63ehflgUT-Me}0;7GivtRjRi*g~HTFR2+_Zu+0>7+CL6Ku=T9XX1G zaY(6JxS_+>8I1-d;i()IYnOygcEgxJ_d2rnmNK}IFx#e_cN{3 z+KQ(`q7(^B*t(p8sdB{u6T(WAjHpCAB_FH!Qx0~uKbMcV>689E($e`({X*9^uBS(h_*%rbxB8obtF>C0An5hFpLK zl79jc1X?6EhT2#HAE8;ScWJ|sQvP({c$~B*@&&iq2pD#D|4>&c6DmfP+QV% z=s|e>R9L7HZsa1i+LeXnMWjr{CH+xZix+8no2ktbfbsUI7y)@tShsp4W)a1C(Fuw4 zhf4LCnn2b?ZAoc+lB*Fj5tY?62BcCoC7MhmQ6LynAEYt?W;#Fzoq|EWll6`WscP%i zN-uPPfFm;=*c-E9VqAJc#F(GxXuQ5ldlV;lgkh0-YD3F_Q^ggmZ@YY3R3y9N!kOeW z-qRfa6fm?4UW!p9{|(xsG%TXf5}2j&!e*lhcDW#c5P`gXK9FWD=N7Txa2ya#@2g#0EfVLj9H@Tp%SquUCf>v*~keD zUYN!g=cL48N?t<@mqX~LMqF*lvMBSyaA$^$=QJfN%07}jFE!#YSRus4b63=M#n5Vf zpL9u`Sm1O&oNUy39lSGx{I6N9F&}f;%}~5BEgHrh2gHG# zqIhGmK_LeODpE#xm73Bm|r`w!;4`oC#bc5Ix<~$^g_pJ=7NQ z(?l)QcVW~grPK!j)I$B#LEY3ut$|4`)m9zVMP1ccJ=91I)mF{aJ-rO?m(^cQ)>G}( zQ=J%HZPr^&)kn?MSH0CtZPre$*2@9bT7A}prqn(CZ&wY~YyH-3{nu`7*M@`FX>HhL zo!E6v)?75#iLKRhjo64i*n-X1i*4D9jno9l*?HaApB>kPJ=k^4*^r&rn@!q^-PULw z*R9>yUTxY~9oT4n+OsX!qD|M4&Dw0e+L0aDhb`H9E!B^`*S8JVseRnIJ=)2A+MvzY zmu=jH4cWF`)zq!r!aWlvqSMTGJl_4?;2qxLJ>EIwUEbz>-sqj)>b>6V-QMo~-tZmY p@;%@5UElV7-}s&1`n})$-QWKG-vA!q0zTjbUf}(Wh}<0z06UO0itGRY literal 0 HcmV?d00001 From 2969518bbb1de6414f3ca0c072970abe496f534f Mon Sep 17 00:00:00 2001 From: Binal Date: Sat, 10 Oct 2020 12:12:07 -0700 Subject: [PATCH 18/49] Fix build issues --- .../ChargesVirologyCoreFormSection.java | 4 ++-- .../ChargesVirologyCoreFormType.java | 2 +- .../notification/FinanceNotification.java | 2 +- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 21 +++++++++++-------- .../buttons/CreateNecropsyRequestButton.java | 2 +- .../buttons/CreateTaskFromRecordButtons.java | 2 +- .../dataentry/AnimalDetailssFormSection.java | 2 +- .../onprc_ehr/dataentry/ArrivalFormType.java | 2 +- .../dataentry/BehaviorExamFormType.java | 2 +- .../CagemateClinicalReportFormType.java | 4 ++-- .../EncounterProcedureFormSection.java | 2 +- .../GrossFindingsFormPanelSection.java | 2 +- .../dataentry/NHPRProcessingFormType.java | 2 +- .../dataentry/NecropsyRequestForm.java | 4 ++-- .../dataentry/ParentageFormType.java | 2 +- .../PathologyDiagnosesFormSection.java | 2 +- .../dataentry/TBTestObservationFormType.java | 4 ++-- .../TissueMeasurementsFormSection.java | 2 +- .../dataentry/TissueWeightsFormSection.java | 2 +- .../dataentry/TreatmentOrdersFormSection.java | 2 +- .../dataentry/TreatmentsFormType.java | 2 +- .../ColonyAlertsNotification.java | 4 ++-- .../onprc_ehr/table/ONPRC_EHRCustomizer.java | 7 ++++--- 23 files changed, 42 insertions(+), 38 deletions(-) diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java index 1736e0ebb..9e91fc4cd 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormSection.java @@ -38,12 +38,12 @@ public ChargesVirologyCoreFormSection(EHRService.FORM_SECTION_LOCATION location) //super("onprc_billing", "virologyCharges", "Virology Charges", "ehr-gridpanel", location); setConfigSources(Collections.singletonList("Task")); setClientStoreClass("EHR.data.MiscChargesClientStore"); - addClientDependency(ClientDependency.fromPath("ehr/data/MiscChargesClientStore.js")); + addClientDependency(ClientDependency.supplierFromPath("ehr/data/MiscChargesClientStore.js")); // setClientStoreClass("EHR.data.VirologyChargesClientStore"); // addClientDependency(ClientDependency.fromPath("ehr/data/VirologyChargesClientStore.js")); - addClientDependency(ClientDependency.fromPath("onprc_billing/model/sources/VirologyMisc.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_billing/model/sources/VirologyMisc.js")); addConfigSource("VirologyMisc"); } diff --git a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java index d707eeddf..ebe351249 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java +++ b/onprc_billing/src/org/labkey/onprc_billing/dataentry/ChargesVirologyCoreFormType.java @@ -31,7 +31,7 @@ public ChargesVirologyCoreFormType(DataEntryFormContext ctx, Module owner) new ChargesVirologyCoreFormSection() )); - addClientDependency(ClientDependency.fromPath("onprc_billing/panel/ChargesInstructionPanel.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_billing/panel/ChargesInstructionPanel.js")); } diff --git a/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java b/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java index 9c2684a40..2c4548de4 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java +++ b/onprc_billing/src/org/labkey/onprc_billing/notification/FinanceNotification.java @@ -806,7 +806,7 @@ private void getSchedulerAliases(Container c, User u, StringBuilder msg) } TableInfo ti = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("SchedulerAliases"); - ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); + ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(c, u)); SimpleFilter filter = new SimpleFilter(FieldKey.fromString("Alias"), null, CompareType.NONBLANK); TableSelector ts = new TableSelector(ti, filter, null); long count = ts.getRowCount(); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index c1e981e77..904bc1ccf 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -63,10 +63,13 @@ import org.labkey.onprc_ehr.dataentry.*; import org.labkey.onprc_ehr.demographics.ActiveAnimalGroupsDemographicsProvider; import org.labkey.onprc_ehr.demographics.ActiveCasesDemographicsProvider; +import org.labkey.onprc_ehr.demographics.ActiveDrugsGivenDemographicsProvider; +import org.labkey.onprc_ehr.demographics.ActiveTreatmentsXDemographicsProvider; import org.labkey.onprc_ehr.demographics.AssignedVetDemographicsProvider; import org.labkey.onprc_ehr.demographics.CagemateInfantDemographicsProvider; import org.labkey.onprc_ehr.demographics.CagematesDemographicsProvider; import org.labkey.onprc_ehr.demographics.FosterChildDemographicsProvider; +import org.labkey.onprc_ehr.demographics.GeneticAncestryDemographicsProvider; import org.labkey.onprc_ehr.demographics.HousingDemographicsProvider; import org.labkey.onprc_ehr.demographics.LastHousingDemographicsProvider; import org.labkey.onprc_ehr.demographics.ParentsDemographicsProvider; @@ -222,7 +225,7 @@ private void registerEHRResources() EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/ClinicalProcedures.js"), this); //Added 11-17-16 KOLLI - // EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/CohortField.js"), this); + // EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/form/field/CohortField.js"), this); //Added: 7-12-2016 R.Blasa EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/SnapshotPanel.js"), this); @@ -240,26 +243,26 @@ private void registerEHRResources() //Added: 10-25-2017 R.Blasa References new Xtype - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/CEG_PlantextArea.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/form/field/CEG_PlantextArea.js"), this); //Added: 7-7-2017 R.Blasa -// EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/HousingReason.js"), this); +// EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/HousingReason.js"), this); //Added: 1-19-2018 R.Blasa - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/AnimalGroupFieldsCombo.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/form/field/AnimalGroupFieldsCombo.js"), this); // //Added: 10-5-2018 R.Blasa //needed for displaying wound subcategory - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/panel/ManageCasesPanel.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/ManageCasesPanel.js"), this); // //Added: 10-8-2018 R.Blasa //needed for displaying wound subcategory - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageCasesWindow.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/window/ManageCasesWindow.js"), this); //Added: 7-18-2018 R.Blasa - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/window/ManageRecordWindow.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/window/ManageRecordWindow.js"), this); //Added: 10-7-2019 R.Blasa - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/TreatmentDrugsClinical.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/TreatmentDrugsClinical.js"), this); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single Housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=demographicsPaired&query.viewName=Single Housed"), "Commonly Used Queries"); @@ -489,7 +492,7 @@ public String toString() EHRService.get().registerDemographicsProvider(new PregnancyConfirmDemographicsProvider(this)); //Added: 3-27-2017 R.Blasa - EHRService.get().registerClientDependency(ClientDependency.fromPath("onprc_ehr/panel/EnterDataPanel.js"), this); + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/EnterDataPanel.js"), this); //Created: 2-21-2017 R.Blasa EHRService.get().registerDemographicsProvider(new CagemateInfantDemographicsProvider(this)); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java index 2089a853e..508863168 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateNecropsyRequestButton.java @@ -10,6 +10,6 @@ public class CreateNecropsyRequestButton extends CreateTaskFromRecordsButton public CreateNecropsyRequestButton(Module owner) { super(owner, "Create Necropsy Request From Selected", "ONPRC_EHR.window.CreateNecropsyRequestWindow.createTaskFromRecordHandler(dataRegionName, '" + NecropsyFormType.NAME + "')"); - setClientDependencies(ClientDependency.fromPath("onprc_ehr/window/CreateNecropsyRequestWindow.js")); + setClientDependencies(ClientDependency.supplierFromPath("onprc_ehr/window/CreateNecropsyRequestWindow.js")); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java index 14bda6595..a51e4092e 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/buttons/CreateTaskFromRecordButtons.java @@ -32,7 +32,7 @@ public class CreateTaskFromRecordButtons extends SimpleButtonConfigFactory public CreateTaskFromRecordButtons(Module owner, String btnLabel, String taskLabel, String formType) { super(owner, btnLabel, "ONPRC_EHR.window.CreateTaskFromRecordsWindow.createTaskFromRecordHandler(dataRegionName, '" + formType + "', '" + taskLabel + "')"); - setClientDependencies(ClientDependency.fromPath("onprc_ehr/window/CreateTaskFromRecordsWindow.js")); //Modified: 1-19-2019 R.Blasa + setClientDependencies(ClientDependency.supplierFromPath("onprc_ehr/window/CreateTaskFromRecordsWindow.js")); //Modified: 1-19-2019 R.Blasa } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java index f55ca91ca..5492e7137 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/AnimalDetailssFormSection.java @@ -25,7 +25,7 @@ public class AnimalDetailssFormSection extends NonStoreFormSection public AnimalDetailssFormSection() { super("AnimalDetails", "Animal Details", "onprc_ehr-animaldetailspanels"); - addClientDependency(ClientDependency.fromPath("onprc_ehr/panel/AnimalDetailsPanel.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/AnimalDetailsPanel.js")); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java index ed0012885..3149d9cba 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ArrivalFormType.java @@ -52,7 +52,7 @@ public ArrivalFormType(DataEntryFormContext ctx, Module owner) // Added: 8-6-2019 R.Blasa - addClientDependency(ClientDependency.fromPath("onprc_ehr/panel/ArrivalDataEntryPanel.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/panel/ArrivalDataEntryPanel.js")); setJavascriptClass("ONPRC_EHR.panel.ArrivalDataEntryPanel"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java index 070f783ad..d889bc93f 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BehaviorExamFormType.java @@ -82,7 +82,7 @@ public BehaviorExamFormType(DataEntryFormContext ctx, Module owner) // //Added: 12-18-2017 R.Blasa setStoreCollectionClass("ONPRC_EHR.data.sources.BehaviorExamStoreCollection"); - addClientDependency(ClientDependency.fromPath("onprc_ehr/data/sources/BehaviorExamStoreCollection.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/data/sources/BehaviorExamStoreCollection.js")); // //Added: 1-23-2018 R.Blasa // Disable as temporary workaround to ticket Ticket 33579: Clinical Staff unsable to Create new Cases diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java index 1c1ff8e3b..25714ace3 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/CagemateClinicalReportFormType.java @@ -50,7 +50,7 @@ public CagemateClinicalReportFormType(DataEntryFormContext ctx, Module owner) )); setStoreCollectionClass("EHR.data.ClinicalReportStoreCollection"); - addClientDependency(ClientDependency.fromPath("ehr/data/ClinicalReportStoreCollection.js")); + addClientDependency(ClientDependency.supplierFromPath("ehr/data/ClinicalReportStoreCollection.js")); setTemplateMode(AbstractFormSection.TEMPLATE_MODE.NO_ID); setDisplayReviewRequired(true); @@ -62,7 +62,7 @@ public CagemateClinicalReportFormType(DataEntryFormContext ctx, Module owner) s.addConfigSource("ClinicalProcedures"); } - addClientDependency(ClientDependency.fromPath("ehr/model/sources/ClinicalDefaults.js")); + addClientDependency(ClientDependency.supplierFromPath("ehr/model/sources/ClinicalDefaults.js")); } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java index 2de80b56e..14cc5b5d4 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/EncounterProcedureFormSection.java @@ -32,7 +32,7 @@ public EncounterProcedureFormSection(EHRService.FORM_SECTION_LOCATION location) { super("study", "encounters", "Procedures", location); //Added 3-30-2017 R.Blasa - addClientDependency(ClientDependency.fromPath("ehr/data/ClinicalEncountersClientStore.js")); + addClientDependency(ClientDependency.supplierFromPath("ehr/data/ClinicalEncountersClientStore.js")); setClientStoreClass("EHR.data.ClinicalEncountersClientStore"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java index 5515935af..8d2c13b3b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/GrossFindingsFormPanelSection.java @@ -34,7 +34,7 @@ public GrossFindingsFormPanelSection() addClientDependency(ClientDependency.supplierFromPath("ehr/window/EncounterAddRecordWindow.js")); //Added: 5-17-2018 R.Blasa - addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/Gross_Finding.css")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/Gross_Finding.css")); addConfigSource("Encounter"); addConfigSource("EncounterChild"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java index d09d1242b..d2bcec99f 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPRProcessingFormType.java @@ -53,7 +53,7 @@ public NHPRProcessingFormType(DataEntryFormContext ctx, Module owner) //Added 5-26-2016 R.Blasa - addClientDependency(ClientDependency.fromPath("/onprc_ehr/model/sources/ProjectAnimalConditions.js")); + addClientDependency(ClientDependency.supplierFromPath("/onprc_ehr/model/sources/ProjectAnimalConditions.js")); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java index 6375fde79..131865f8b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NecropsyRequestForm.java @@ -26,8 +26,8 @@ public NecropsyRequestForm(DataEntryFormContext ctx, Module owner) new SimpleFormSection("study", "tissue_samples", "Tissue Samples", "onprc_ehr-dragdropgridpanel"), new SimpleFormSection("study", "organ_weights", "Organ Weights", "onprc_ehr-dragdropgridpanel") )); - addClientDependency(ClientDependency.fromPath("onprc_ehr/grid/DragDropGridPanel.js")); - addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/ClinicalEncounters.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/grid/DragDropGridPanel.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/ClinicalEncounters.js")); for (FormSection s : getFormSections()) s.addConfigSource("ClinicalEncounters"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java index bc80b7d76..29ab619bf 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ParentageFormType.java @@ -51,6 +51,6 @@ public ParentageFormType(DataEntryFormContext ctx, Module owner) //Added 5-26-2016 R.Blasa - addClientDependency(ClientDependency.fromPath("/onprc_ehr/model/sources/Parentage_Properties.js")); + addClientDependency(ClientDependency.supplierFromPath("/onprc_ehr/model/sources/Parentage_Properties.js")); } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java index 4d7c8c251..270701803 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathologyDiagnosesFormSection.java @@ -40,7 +40,7 @@ public PathologyDiagnosesFormSection(String schemaName, String queryName, String setXtype("onprc_ehr-dragdropgridpanel"); //Added: 10-31-2018 R.Blasa address issues with text font size - addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/Gross_Finding.css")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/Gross_Finding.css")); } // Added: 6-26-2017 R.Blasa Include tool bar at bottom grid diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java index 3b3210202..d6b80ece2 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TBTestObservationFormType.java @@ -46,9 +46,9 @@ public TBTestObservationFormType(DataEntryFormContext ctx, Module owner) } - addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/TB_TestObservation.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/TB_TestObservation.js")); - addClientDependency(ClientDependency.fromPath("onprc_ehr/form/field/TB_TST_Scores_Type.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/form/field/TB_TST_Scores_Type.js")); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java index 3130cd15a..032b9e9f2 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueMeasurementsFormSection.java @@ -30,7 +30,7 @@ public TissueMeasurementsFormSection() super("study", "measurements", "Measurements"); setLocation(EHRService.FORM_SECTION_LOCATION.Tabs); setXtype("onprc_ehr-dragdropgridpanel"); - addClientDependency(ClientDependency.fromPath("onprc_ehr/grid/DragDropGridPanel.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/grid/DragDropGridPanel.js")); } // Added: 6-26-2017 R.Blasa Include tool bar at bottom grid diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java index ed5e07633..3327da6b2 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TissueWeightsFormSection.java @@ -31,7 +31,7 @@ public TissueWeightsFormSection() super("study", "tissue_samples", "Tissues/Weights"); setLocation(EHRService.FORM_SECTION_LOCATION.Tabs); setXtype("onprc_ehr-dragdropgridpanel"); - addClientDependency(ClientDependency.fromPath("onprc_ehr/grid/DragDropGridPanel.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/grid/DragDropGridPanel.js")); } // Added: 6-26-2017 R.Blasa Include tool bar at bottom grid diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java index 3ce62f3ba..788b1fcfe 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentOrdersFormSection.java @@ -43,7 +43,7 @@ public TreatmentOrdersFormSection(EHRService.FORM_SECTION_LOCATION location) // Modified: 7-29-2020 Set Remarks information setClientStoreClass("ONPRC_EHR.data.TreatmentOrdersClientStore"); - addClientDependency(ClientDependency.fromPath("onprc_ehr/data/sources/TreatmentOrdersClientStore.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/data/sources/TreatmentOrdersClientStore.js")); } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java index 326191507..8b6319e44 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/TreatmentsFormType.java @@ -57,7 +57,7 @@ public TreatmentsFormType(DataEntryFormContext ctx, Module owner) s.addConfigSource("TreatmentDrugsClinical"); } - addClientDependency(ClientDependency.fromPath("onprc_ehr/model/sources/TreatmentDrugsClinical.js")); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/TreatmentDrugsClinical.js")); if (ctx.getContainer().getActiveModules().contains(ModuleLoader.getInstance().getModule("onprc_billing"))) { diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index 04236193c..1cef24377 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -1062,13 +1062,13 @@ protected void pmicSchedulerAlert(final Container c, User u, final StringBuilder } //Daily events query TableInfo ti = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler"); - ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); + ((ContainerFilterable) ti).setContainerFilter(ContainerFilter.Type.AllFolders.create(c, u)); TableSelector ts = new TableSelector(ti, null, null); long count = ts.getRowCount(); //Weekly events query TableInfo ti1 = QueryService.get().getUserSchema(u, c, "extscheduler").getTable("PMIC_Scheduler_Weekly"); - ((ContainerFilterable) ti1).setContainerFilter(ContainerFilter.Type.AllFolders.create(u)); + ((ContainerFilterable) ti1).setContainerFilter(ContainerFilter.Type.AllFolders.create(c, u)); TableSelector ts1 = new TableSelector(ti1, null, null); long count1 = ts1.getRowCount(); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java index f545ef489..a8a298b20 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/table/ONPRC_EHRCustomizer.java @@ -26,6 +26,7 @@ import org.labkey.api.data.DisplayColumn; import org.labkey.api.data.DisplayColumnFactory; import org.labkey.api.data.JdbcType; +import org.labkey.api.data.MutableColumnInfo; import org.labkey.api.data.RenderContext; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.TableInfo; @@ -2198,10 +2199,10 @@ public TableInfo getLookupTableInfo() return null; } - ti.getColumn(pkCol.getName()).setHidden(true); - ti.getColumn(pkCol.getName()).setKeyField(true); + ((MutableColumnInfo)ti.getColumn(pkCol.getName())).setHidden(true); + ((MutableColumnInfo)ti.getColumn(pkCol.getName())).setKeyField(true); - ti.getColumn("flagsAlertsActive").setLabel("Flags Alerts Active"); + ((MutableColumnInfo)ti.getColumn("flagsAlertsActive")).setLabel("Flags Alerts Active"); return ti; } From 9d23eeffa8ab282ef3c9284d016cc77a43660ec1 Mon Sep 17 00:00:00 2001 From: Binal Date: Sat, 10 Oct 2020 12:40:48 -0700 Subject: [PATCH 19/49] Merge from onprc19.1Prod r 65762 to 65949 --- .../resources/etls/rateChangeUpdate.xml | 27 - .../onprc_billing/LeaseFee_Demographics.sql | 2 +- .../resources/schemas/onprc_billing.xml | 1 + .../resources/views/financeManagement.html | 8 +- .../NIHIndustryRates.query.xml | 3 +- .../NIHRates_ReducedFA.sql | 24 +- onprc_ehr/resources/etls/TreatmentToDrug.xml | 14 - onprc_ehr/resources/etls/eIACUCToPrimce.xml | 111 ----- .../queries/ehr/requests/Requests.qview.xml | 20 + .../queries/ehr_lookups/snomed/.qview.xml | 12 + .../queries/study/ActiveStudyDetails.sql | 21 + .../resources/queries/study/StudyDetails.js | 32 ++ .../queries/study/StudyDetails.query.xml | 105 ++++ .../study/StudyDetailsHistory.query.xml | 12 + .../queries/study/StudyDetailsHistory.sql | 40 ++ .../StudyDetails_cohort_values.query.xml | 18 + .../study/StudyDetails_cohort_values.sql | 2 + .../study/StudyDetails_group_values.query.xml | 18 + .../study/StudyDetails_group_values.sql | 2 + .../study/StudyDetails_phase_values.query.xml | 18 + .../study/StudyDetails_phase_values.sql | 2 + .../sqlserver/onprc_ehr-20.415-20.416.sql | 78 +++ .../sqlserver/onprc_ehr-20.416-20.417.sql | 20 + onprc_ehr/resources/schemas/onprc_ehr.xml | 59 ++- .../scripts/onprc_ehr/onprc_triggers.js | 7 + .../resources/views/Covid19Scheduler.html | 17 +- onprc_ehr/resources/views/projectDetails.html | 2 +- .../resources/views/protocolDetails.html | 2 +- .../buttons/bulkEditRequestButtons.js | 1 + .../onprc_ehr/model/sources/ASB_Services.js | 4 +- .../model/sources/StudyDetailsProperties.js | 95 ++++ .../resources/web/onprc_ehr/onprcReports.js | 2 +- .../onprc_ehr/window/CreateProjectWindow.js | 1 + .../web/onprc_ehr/window/SedationWindow.js | 463 ++++++++++++++++++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 27 +- .../dataentry/AuxProcedureFormType.java | 2 +- .../DrugAdministrationFormSection.java | 112 +++++ .../dataentry/PathDeathFormType.java | 56 +++ .../dataentry/StudyDetailsFormSection.java | 25 + .../dataentry/TreatmentOrdersFormSection.java | 1 - .../query/ONPRC_EHRTriggerHelper.java | 148 ++++-- .../onprc_ehr/table/ONPRC_EHRCustomizer.java | 4 +- 42 files changed, 1362 insertions(+), 256 deletions(-) delete mode 100644 onprc_billing/resources/etls/rateChangeUpdate.xml delete mode 100644 onprc_ehr/resources/etls/TreatmentToDrug.xml delete mode 100644 onprc_ehr/resources/etls/eIACUCToPrimce.xml create mode 100644 onprc_ehr/resources/queries/ehr/requests/Requests.qview.xml create mode 100644 onprc_ehr/resources/queries/ehr_lookups/snomed/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/ActiveStudyDetails.sql create mode 100644 onprc_ehr/resources/queries/study/StudyDetails.js create mode 100644 onprc_ehr/resources/queries/study/StudyDetails.query.xml create mode 100644 onprc_ehr/resources/queries/study/StudyDetailsHistory.query.xml create mode 100644 onprc_ehr/resources/queries/study/StudyDetailsHistory.sql create mode 100644 onprc_ehr/resources/queries/study/StudyDetails_cohort_values.query.xml create mode 100644 onprc_ehr/resources/queries/study/StudyDetails_cohort_values.sql create mode 100644 onprc_ehr/resources/queries/study/StudyDetails_group_values.query.xml create mode 100644 onprc_ehr/resources/queries/study/StudyDetails_group_values.sql create mode 100644 onprc_ehr/resources/queries/study/StudyDetails_phase_values.query.xml create mode 100644 onprc_ehr/resources/queries/study/StudyDetails_phase_values.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.415-20.416.sql create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.416-20.417.sql create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/StudyDetailsProperties.js create mode 100644 onprc_ehr/resources/web/onprc_ehr/window/SedationWindow.js create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/DrugAdministrationFormSection.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PathDeathFormType.java create mode 100644 onprc_ehr/src/org/labkey/onprc_ehr/dataentry/StudyDetailsFormSection.java diff --git a/onprc_billing/resources/etls/rateChangeUpdate.xml b/onprc_billing/resources/etls/rateChangeUpdate.xml deleted file mode 100644 index 7de179347..000000000 --- a/onprc_billing/resources/etls/rateChangeUpdate.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - ratechangeUpdate - - Updates the Rate Sheets for Investigators in the Billing Public Folder - - - - - Runs a stored procedure to update the Rate Sheet for Public Rate Projections. - - - - - - - - - - - - - - - diff --git a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql index c0c1d8623..06c95cdfe 100644 --- a/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql +++ b/onprc_billing/resources/queries/onprc_billing/LeaseFee_Demographics.sql @@ -77,7 +77,7 @@ End as MultipleAssignments, -- When (da.project is not null and da.projectCategory = 'Resource') and da.dualassignment = a.project then da.project.name -- else null da.projectName as CreditResource, - da.project.Account as CreditTo, + da.projectAccount as CreditTo, --Case -- When (da.project is not null and da.projectCategory = 'Resource') and da.dualassignment = a.project then da.project.account -- else null diff --git a/onprc_billing/resources/schemas/onprc_billing.xml b/onprc_billing/resources/schemas/onprc_billing.xml index 41df2bf2b..aa5ae30ce 100644 --- a/onprc_billing/resources/schemas/onprc_billing.xml +++ b/onprc_billing/resources/schemas/onprc_billing.xml @@ -299,6 +299,7 @@ + Ext4 ehr.context /onprc_billing/window/ReverseChargeWindow.js diff --git a/onprc_billing/resources/views/financeManagement.html b/onprc_billing/resources/views/financeManagement.html index eb3e870f7..7ef0c6308 100644 --- a/onprc_billing/resources/views/financeManagement.html +++ b/onprc_billing/resources/views/financeManagement.html @@ -54,13 +54,7 @@ items: [ {name: 'IACUC Protocols', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', ctx.EHRStudyContainer, {schemaName: 'ehr', 'query.queryName': 'protocol'})}, {name: 'ONPRC Projects', url: LABKEY.ActionURL.buildURL(queryController, queryAction, ctx.EHRStudyContainer, {schemaName: 'ehr', 'query.queryName': 'project', showImport: true})}, - - {name: 'Grants', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'grants', 'query.viewName': 'Active Grants'})}, - {name: 'Grant Projects', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'onprc_billing', 'query.queryName': 'grantProjects', 'query.viewName': 'Active Grant Projects'})}, - {name: 'Aliases', url: LABKEY.ActionURL.buildURL(queryController, queryAction, null, {schemaName: 'onprc_billing', 'query.queryName': 'aliases', 'query.viewName': 'Active Aliases'})}, - - //{name: 'Approved IACUC Funding Sources', url: LABKEY.ActionURL.buildURL(queryController, queryAction, ctx.EHRStudyContainer, {schemaName: 'onprc_billing', 'query.queryName': 'iacucFundingSources'})}, - + {name: 'Aliases (Grants Data included)', url: LABKEY.ActionURL.buildURL(queryController, queryAction, null, {schemaName: 'onprc_billing', 'query.queryName': 'aliases', 'query.viewName': 'Active Aliases'})}, {name: 'Investigators', url: LABKEY.ActionURL.buildURL(queryController, queryAction, ctx.EHRStudyContainer, {schemaName: 'onprc_ehr', 'query.queryName': 'investigators', showImport: true})}, {name: 'Financial Analysts', url: LABKEY.ActionURL.buildURL(queryController, queryAction, ctx.EHRStudyContainer, {schemaName: 'onprc_billing', 'query.queryName': 'fiscalAuthorities', showImport: true})}, {name: 'OGA Raw Data', url: LABKEY.ActionURL.buildURL('query', 'executeQuery', null, {schemaName: 'OGA', 'query.queryName': 'ZGMS_PRIM_ALL_V'})} diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml index 6994f26e1..aad927725 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHIndustryRates.query.xml @@ -1,5 +1,4 @@ - -query xmlns="http://labkey.org/data/xml/query"> + diff --git a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.sql b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.sql index 2d5c640ed..e9d5e4447 100644 --- a/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.sql +++ b/onprc_billingpublic/resources/queries/onprc_billing_public/NIHRates_ReducedFA.sql @@ -1,14 +1,16 @@ PARAMETERS (ProjectFA DOUBLE DEFAULT .2) SELECT n.category, -n.name, -(n.UnitCost *(1+(.47 - ProjectFA))) as CurrentYear, -(n.year1 *(1+(.47 - ProjectFA))) as Year1, -(n.year2 *(1+(.47 - ProjectFA))) as Year2, -(n.year3 *(1+(.47 - ProjectFA))) as Year3, -(n.year4 *(1+(.47 - ProjectFA))) as Year4, -(n.year5 *(1+(.47 - ProjectFA))) as Year5, -(n.year6 *(1+(.47 - ProjectFA))) as Year6, -(n.year7 *(1+(.47 - ProjectFA))) as Year7, -(n.year8 *(1+(.47 - ProjectFA))) as Year8, -n.PostedDate + n.name, + n.unitcost, + (1.47 / (1 + ProjectFA)) as NewRateCalc, + (n.UnitCost *(1.47 / (1 + ProjectFA))) as CurrentYear, + (n.year1 *(1.47 / (1 + ProjectFA))) as Year1, + (n.year2 *(1.47 / (1 + ProjectFA))) as Year2, + (n.year3 *(1.47 / (1 + ProjectFA))) as Year3, + (n.year4 *(1.47 / (1 + ProjectFA))) as Year4, + (n.year5 *(1.47 / (1 + ProjectFA))) as Year5, + (n.year6 *(1.47 / (1 + ProjectFA))) as Year6, + (n.year7 *(1.47 / (1 + ProjectFA))) as Year7, + (n.year8 *(1.47 / (1 + ProjectFA))) as Year8, + n.PostedDate FROM NIHRateConfig n \ No newline at end of file diff --git a/onprc_ehr/resources/etls/TreatmentToDrug.xml b/onprc_ehr/resources/etls/TreatmentToDrug.xml deleted file mode 100644 index c5df5d329..000000000 --- a/onprc_ehr/resources/etls/TreatmentToDrug.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - TreatmentToDrug - Transfers from the treatmentProcessing table in Study to the Drug table in Study - - - Transfer to Drug Table - - - - - - - diff --git a/onprc_ehr/resources/etls/eIACUCToPrimce.xml b/onprc_ehr/resources/etls/eIACUCToPrimce.xml deleted file mode 100644 index 1a5f9a847..000000000 --- a/onprc_ehr/resources/etls/eIACUCToPrimce.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - eiACUCtoPrime - - Transfers from the eIACUC Import tables to the Prime tables in ONPRC_EHRy - - - - - - - - Transfer to eIACUC Animal Groups - - - - - - - - - - Transfer to IBX Numbers - - - - - - - - - - Transfer to Non Surgical Procedures - - - - - - - - - - Transfer to Protocols - - - - - - - - - - - Transfer to Surgical Procedures - - - - - - - - - - - - - - - - - - diff --git a/onprc_ehr/resources/queries/ehr/requests/Requests.qview.xml b/onprc_ehr/resources/queries/ehr/requests/Requests.qview.xml new file mode 100644 index 000000000..40b99e5c3 --- /dev/null +++ b/onprc_ehr/resources/queries/ehr/requests/Requests.qview.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/ehr_lookups/snomed/.qview.xml b/onprc_ehr/resources/queries/ehr_lookups/snomed/.qview.xml new file mode 100644 index 000000000..467820a1e --- /dev/null +++ b/onprc_ehr/resources/queries/ehr_lookups/snomed/.qview.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/ActiveStudyDetails.sql b/onprc_ehr/resources/queries/study/ActiveStudyDetails.sql new file mode 100644 index 000000000..07d04c5e6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/ActiveStudyDetails.sql @@ -0,0 +1,21 @@ +Select + Id, + project, project.protocol, project.protocol.investigatorId, + Date StartDate, endDate, + studyCohort, + studyGroup, + studyGroupNum, + studyPhase, + remark, + performedby, + Id.demographics.calculated_status, + Id.demographics.gender, + Id.curLocation.room, + Id.curLocation.cage, + taskid +From Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.StudyDetails +Where (curdate() between Date and endDate) OR ( (curdate() >= Date) and (endDate IS NULL)) + + + + diff --git a/onprc_ehr/resources/queries/study/StudyDetails.js b/onprc_ehr/resources/queries/study/StudyDetails.js new file mode 100644 index 000000000..43d63ca92 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010-2015 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ + +require("ehr/triggers").initScript(this); +var ONPRC_triggerHelper = new org.labkey.onprc_ehr.query.ONPRC_EHRTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); + +//Added by Kolli on 3/3/2020. This function automatically sets the study details endDate if previous study details endDate is empty when a new study is created. +function onComplete(event, errors, triggerHelper){ + if (!triggerHelper.isETL() && !triggerHelper.isValidateOnly()){ + var studyRows = triggerHelper.getRows(); + var idsToClose = []; + if (studyRows){ + for (var i=0;i + + + +
    + + Study Details + + + true + + + + Id + + + + Center Project + false + + + + Start Date + + + + End Date + + + + Study Cohort + + + + Study Group + + study + StudyDetails_group_values + value + + + + + Study Group # + + study + StudyDetails_cohort_values + value + + + + + Study Phase + + study + StudyDetails_phase_values + value + + + + + Remark + + + + + study + qcstate + RowId + + + + + Task Id + + ehr + tasks + taskid + + + + true + + + Performed by + + + true + + + + + true + + + + + true + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetailsHistory.query.xml b/onprc_ehr/resources/queries/study/StudyDetailsHistory.query.xml new file mode 100644 index 000000000..35e46432e --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetailsHistory.query.xml @@ -0,0 +1,12 @@ + + + + + Study Details + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetailsHistory.sql b/onprc_ehr/resources/queries/study/StudyDetailsHistory.sql new file mode 100644 index 000000000..a449e3415 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetailsHistory.sql @@ -0,0 +1,40 @@ +Select + Id, + project, project.protocol, project.protocol.investigatorId, + Date StartDate, endDate, + studyCohort, + studyGroup, + studyGroupNum, + studyPhase, + remark, + performedby, + Id.demographics.calculated_status, + Id.demographics.gender, + CASE + --if enddate is null and start date is before the current date - list current room & cage + WHEN endDate IS NULL AND Date <= curDate() THEN Id.curLocation.room + --if endate is null and start date is a future date - do not list room & cage + WHEN endDate IS NULL AND Date >= curDate() THEN NULL + --if enddate is before the current date - list room & cage at time of enddate + WHEN endDate <= curDate() AND Date <= curDate() THEN (Select h.room From housing h + Where (h.Id = Id) And (h.date <= endDate and h.enddateCoalesced >= endDate) ORDER BY h.date DESC LIMIT 1) + --if enddate is a future date and start date is before the current date - list current room & cage + WHEN endDate >= curDate() AND Date <= curDate() THEN Id.curLocation.room + ELSE NULL + END AS Room, + CASE + --if enddate is null and start date is before the current date - list current room & cage + WHEN endDate IS NULL AND Date <= curDate() THEN Id.curLocation.cage + --if endate is null and start date is a future date - do not list room & cage + WHEN endDate IS NULL AND Date >= curDate() THEN NULL + --if enddate is before the current date - list room & cage at time of enddate + WHEN endDate <= curDate() AND Date <= curDate() THEN (Select h.cage From housing h + Where (h.Id = Id) And (h.date <= endDate and h.enddateCoalesced >= endDate) ORDER BY h.date DESC LIMIT 1) + --(h.Id = Id And h.enddate IS NULL) + --OR (h.Id = Id And h.enddate IS NOT NULL And (endDate between h.date and h.enddate)) + --if enddate is a future date and start date is before the current date - list current room & cage + WHEN endDate >= curDate() AND Date <= curDate() THEN Id.curLocation.cage + ELSE NULL + END AS Cage, + taskid +From Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.study.StudyDetails \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetails_cohort_values.query.xml b/onprc_ehr/resources/queries/study/StudyDetails_cohort_values.query.xml new file mode 100644 index 000000000..a3816e289 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails_cohort_values.query.xml @@ -0,0 +1,18 @@ + + + + + Study Details + + + true + false + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetails_cohort_values.sql b/onprc_ehr/resources/queries/study/StudyDetails_cohort_values.sql new file mode 100644 index 000000000..91471de5e --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails_cohort_values.sql @@ -0,0 +1,2 @@ +SELECT value, name, sort_order from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.onprc_ehr.StudyDetails_Reference_Data +where name like 'Study_Cohort' and dateDisabled is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetails_group_values.query.xml b/onprc_ehr/resources/queries/study/StudyDetails_group_values.query.xml new file mode 100644 index 000000000..a3816e289 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails_group_values.query.xml @@ -0,0 +1,18 @@ + + + + + Study Details + + + true + false + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetails_group_values.sql b/onprc_ehr/resources/queries/study/StudyDetails_group_values.sql new file mode 100644 index 000000000..f8cb8f492 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails_group_values.sql @@ -0,0 +1,2 @@ +SELECT value, name, sort_order from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.onprc_ehr.StudyDetails_Reference_Data +where name like 'Study_Group' and dateDisabled is null \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetails_phase_values.query.xml b/onprc_ehr/resources/queries/study/StudyDetails_phase_values.query.xml new file mode 100644 index 000000000..a3816e289 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails_phase_values.query.xml @@ -0,0 +1,18 @@ + + + + + Study Details + + + true + false + + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/StudyDetails_phase_values.sql b/onprc_ehr/resources/queries/study/StudyDetails_phase_values.sql new file mode 100644 index 000000000..aa15a28e6 --- /dev/null +++ b/onprc_ehr/resources/queries/study/StudyDetails_phase_values.sql @@ -0,0 +1,2 @@ +SELECT value, name, sort_order from Site.{substitutePath moduleProperty('EHR','EHRStudyContainer')}.onprc_ehr.StudyDetails_Reference_Data +where name like 'Study_Phase' and dateDisabled is null \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.415-20.416.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.415-20.416.sql new file mode 100644 index 000000000..1d6341c92 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.415-20.416.sql @@ -0,0 +1,78 @@ + +/****** Object: StoredProcedure [onprc_ehr].[PotentialDam_Insert] Script Date: 4/22/2020 10:16:00 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- ============================================= +-- Author: jonesga@ohsu.edu +-- Create date: 2020-04-22 +-- Modified 2020-08024 +-- reset the gender to f was incorrectly set to M returning Male +-- Description: SP runs a query to populate the Potential Sire Dataset +-- Peer Review +-- ============================================= + ALTER PROCEDURE [onprc_ehr].[PotentialDam_Insert] + + AS + BEGIN + --Potential Sire Query +--This will be used in generation of potential parents + Truncate table [onprc_ehr].[PotentialDam_source] + INSERT INTO [onprc_ehr].[PotentialDam_source] + ([participantId] + ,[Date] + ,[Species] + ,[room] + ,[cage] + ,[DamAgeAtTime] + ,[PotentialDam] + ,[DamBirth] + ,[Damgender] + ,[DamSpecies] + ,[DamDeath] + ,[created] + ,[createdBy] + ,[modified] + ,[modifiedBy] + ,[container] + ) + select + b.participantid, + b.date, + b.species, + b.room, + b.cage, + DateDiff(day, d.birth, b.date) / 365 as SireAgeAtTime, +-- (timestampdiff('SQL_TSI_DAY', h.Id.demographics.birth, b.date) / 365) as damAgeAtTime +-- we want a list of potential dams that were of age at the time of the infants birth +-- So look at the housing table match the Room and Cage on that date + h.participantID, + d.birth as SireBirth, + d.gender, + d.species, + d.death as SireDeath, + GETDATE(), + 1011, + GetDate(), + 1011, + 'CD17027B-C55F-102F-9907-5107380A54BE' + from [studyDataset].[c6d202_birth] b + join [studyDataset].[c6d194_housing] h on + (b.participantId != h.participantId AND + (h.date <= b.date AND h.enddate >= b.date) AND + h.room = b.room AND (h.cage = b.cage OR (h.cage is null and b.cage is null)) + --note: this is to always include observed parents + OR h.participantid = b.dam + ) + join [studyDataset].[c6d203_demographics] d on d.participantid = h.participantid + join [studyDataset].[c6d203_demographics] d1 on d1.participantID = b.participantid + WHERE d.gender = 'f' and DateDiff(day, d.birth, b.date) > 912.5 --(2.5 years) + AND d.species = d1.species + + + + + + + END diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.416-20.417.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.416-20.417.sql new file mode 100644 index 000000000..ddf6ca201 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-20.416-20.417.sql @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS [onprc_ehr].[StudyDetails_Reference_Data] +GO + +/****** Object: Table [onprc_ehr].[StudyDetails_Reference_Data] Script Date: 2/20/2020 ******/ + +CREATE TABLE [onprc_ehr].[StudyDetails_Reference_Data]( + [rowId] INT IDENTITY(1,1)NOT NULL, + [value] [nvarchar](1000) NULL, + [name] [nvarchar](1000) NULL, + [remark] [nvarchar](4000) NULL, + [sort_order] INT NULL, + [dateDisabled] [datetime] NULL, + [created] [datetime] NULL, + [createdBy] [int] NULL, + [modified] [datetime] NULL, + [modifiedBy] [int] NULL + + CONSTRAINT pk_StudyDetails_Reference_Data PRIMARY KEY (rowId) + ) +GO \ No newline at end of file diff --git a/onprc_ehr/resources/schemas/onprc_ehr.xml b/onprc_ehr/resources/schemas/onprc_ehr.xml index 26e520075..d71013056 100644 --- a/onprc_ehr/resources/schemas/onprc_ehr.xml +++ b/onprc_ehr/resources/schemas/onprc_ehr.xml @@ -299,9 +299,9 @@ Reason For Move - - - + + + @@ -383,8 +383,8 @@ Grid Views - - Charts + + Reports Export @@ -392,6 +392,9 @@ Print + + Paging +
    @@ -415,6 +418,7 @@
    + Encounter Summaries Remarks @@ -498,7 +502,7 @@ - core + study qcstate RowId @@ -527,4 +531,45 @@
    - \ No newline at end of file + + + + StudyDetails_Reference_Data + + DETAILED + + + true + + + + Value + + + + Name + + + + + End Date + + + + Sort Order + + + + true + + + + true + + + + +
    + + + diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index c50d79184..ea7f89d2b 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -157,6 +157,13 @@ exports.init = function(EHR){ } }); + //Added: kollil, 5/12/2020 + //Allow to enter future start dates + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'StudyDetails', function(event, helper){ + helper.setScriptOptions({ + allowFutureDates: true + }); + }); //Added: 7-19-2019 R.Blasa EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'Demographics', function(event, helper){ diff --git a/onprc_ehr/resources/views/Covid19Scheduler.html b/onprc_ehr/resources/views/Covid19Scheduler.html index f618dec2e..48356a110 100644 --- a/onprc_ehr/resources/views/Covid19Scheduler.html +++ b/onprc_ehr/resources/views/Covid19Scheduler.html @@ -2,25 +2,10 @@ - ONPRC Covid 19 Test SCheduler + ONPRC Covid 19 Test Scheduler -