diff --git a/nirc_ehr/resources/queries/study/clinical_observations.js b/nirc_ehr/resources/queries/study/clinical_observations.js index 14773397..0875475b 100644 --- a/nirc_ehr/resources/queries/study/clinical_observations.js +++ b/nirc_ehr/resources/queries/study/clinical_observations.js @@ -45,6 +45,12 @@ function onUpsert(helper, scriptErrors, row, oldRow) { EHR.Server.Utils.addError(scriptErrors, 'remark', "You selected 'Yes' for " + row.category + ", please explain in the Remark", "WARN"); } + // The Observations form leaves the type blank; derive it from the observation type's category. + // Every other form sets it explicitly, so those rows pass through untouched. + if (!row.type) { + row.type = triggerHelper.getObservationTypeCategory(row.category) === 'Behavior' ? 'Behavior' : 'Clinical'; + } + // Handle scheduled observations if (!helper.isValidateOnly() && row.scheduledDate) { var qc; diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/ObsDefaults.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/ObsDefaults.js index 73b8950a..ed9e2e4d 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/ObsDefaults.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/ObsDefaults.js @@ -6,6 +6,13 @@ EHR.model.DataModelManager.registerMetadata('ObsDefaults', { byQuery: { 'study.clinical_observations': { + // This form offers every observation type, so it can't know the observation's type up front. + // Clearing the default inherited from ClinicalDefaults lets the trigger script derive it + // from the selected type's category. + type: { + hidden: true, + defaultValue: null + }, category: { lookup: { columns: 'value,description', diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehaviorRoundsFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehaviorRoundsFormType.java index b8b5d404..508259ad 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehaviorRoundsFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehaviorRoundsFormType.java @@ -46,7 +46,7 @@ public NIRCBehaviorRoundsFormType(DataEntryFormContext ctx, Module owner) new NIRCAnimalDetailsFormSection(), new NIRCCaseTemplateFormSection("Case Template", "Case Template", "nirc_ehr-casetemplatepanel", Arrays.asList(ClientDependency.supplierFromPath("nirc_ehr/panel/CaseTemplatePanel.js"))), new NIRCCasesFormPanelSection("Behavior Case", ctx, true), - new NIRCClinicalObservationsFormSection(true, "cases"), + new NIRCClinicalObservationsFormSection(null, true, "cases"), new NIRCTreatmentGivenFormSection(true, "cases") )); diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehavioralCasesFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehavioralCasesFormType.java index d3fed1b4..55222831 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehavioralCasesFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBehavioralCasesFormType.java @@ -50,7 +50,7 @@ public NIRCBehavioralCasesFormType(DataEntryFormContext ctx, Module owner) new NIRCCaseTemplateFormSection("Case Template", "Case Template", "nirc_ehr-casetemplatepanel", Arrays.asList(ClientDependency.supplierFromPath("nirc_ehr/panel/CaseTemplatePanel.js"))), new NIRCCasesFormPanelSection("Behavior Case", ctx, true), new NIRCClinicalRemarksFormPanelSection(true, "cases", "Behavior Assessment", ctx, true), - new NIRCClinicalObservationsFormSection(true, "cases"), + new NIRCClinicalObservationsFormSection(null, true, "cases"), new NIRCObservationOrdersFormSection(null, true, "cases"), new NIRCTreatmentGivenFormSection(true, "cases"), new NIRCTreatmentOrderFormSection(true, "cases") diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkBehaviorFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkBehaviorFormType.java index 911cb28f..340525af 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkBehaviorFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkBehaviorFormType.java @@ -45,8 +45,8 @@ public NIRCBulkBehaviorFormType(DataEntryFormContext ctx, Module owner) new NIRCClinicalRemarksFormSection("Behavior Assessment", ctx.getContainer().hasPermission(ctx.getUser(), NIRCEHRVetTechPermission.class), ctx.getContainer().hasPermission(ctx.getUser(), EHRVeterinarianPermission.class), ctx.getContainer().hasPermission(ctx.getUser(), AdminPermission.class)), - new NIRCClinicalObservationsFormSection(false, null), - new NIRCObservationOrdersFormSection("NIRC_DAILY_CLINICAL_OBS_ORDERS", false, null), + new NIRCClinicalObservationsFormSection(null, false, null), + new NIRCObservationOrdersFormSection(null, false, null), new NIRCTreatmentGivenFormSection(), new NIRCTreatmentOrderFormSection() )); diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkClinicalFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkClinicalFormType.java index ab67a644..ca5b61dd 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkClinicalFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCBulkClinicalFormType.java @@ -51,7 +51,7 @@ public NIRCBulkClinicalFormType(DataEntryFormContext ctx, Module owner) ctx.getContainer().hasPermission(ctx.getUser(), EHRVeterinarianPermission.class), ctx.getContainer().hasPermission(ctx.getUser(), AdminPermission.class)), new NIRCWeightFormSection(true, true), - new NIRCClinicalObservationsFormSection(false, null), + new NIRCClinicalObservationsFormSection("NIRC_DAILY_CLINICAL_OBS", false, null), new NIRCObservationOrdersFormSection("NIRC_DAILY_CLINICAL_OBS_ORDERS", false, null), new NIRCProcedureFormSection(), new NIRCProcedureOrderFormSection(), diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCCasesFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCCasesFormType.java index 7999442b..e88336a9 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCCasesFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCCasesFormType.java @@ -58,7 +58,7 @@ public NIRCCasesFormType(DataEntryFormContext ctx, Module owner) new NIRCCasesFormPanelSection("Clinical Case", ctx, false), new NIRCClinicalRemarksFormPanelSection(true, "cases", "Clinical Remarks", ctx, false), new NIRCWeightFormSection(true, false, true, "cases"), - new NIRCClinicalObservationsFormSection(true, "cases"), + new NIRCClinicalObservationsFormSection("NIRC_DAILY_CLINICAL_OBS", true, "cases"), new NIRCObservationOrdersFormSection(null, true, "cases"), new NIRCProcedureFormSection(true, "cases"), new NIRCProcedureOrderFormSection(true, "cases"), diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalObservationsFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalObservationsFormType.java index a391fefc..86d33539 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalObservationsFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalObservationsFormType.java @@ -37,7 +37,7 @@ public NIRCClinicalObservationsFormType(DataEntryFormContext ctx, Module owner) super(ctx, owner, NAME, NAME, "Clinical", Arrays.asList( new NIRCTaskFormSection(), new NIRCAnimalDetailsFormSection(), - new NIRCClinicalObservationsFormSection(false, false), + new NIRCClinicalObservationsFormSection("NIRC_DAILY_CLINICAL_OBS", false), new NIRCWeightFormSection(true, true) )); diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalRoundsFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalRoundsFormType.java index 4587f2e5..84083fee 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalRoundsFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalRoundsFormType.java @@ -50,7 +50,7 @@ public NIRCClinicalRoundsFormType(DataEntryFormContext ctx, Module owner) new NIRCCaseTemplateFormSection("Case Template", "Case Template", "nirc_ehr-casetemplatepanel", Arrays.asList(ClientDependency.supplierFromPath("nirc_ehr/panel/CaseTemplatePanel.js"))), new NIRCCasesFormPanelSection("Clinical Case", ctx, false), new NIRCWeightFormSection(true, false, true, "cases"), - new NIRCClinicalObservationsFormSection(true, "cases"), + new NIRCClinicalObservationsFormSection("NIRC_DAILY_CLINICAL_OBS", true, "cases"), new NIRCProcedureFormSection(true, "cases"), new NIRCTreatmentGivenFormSection(true, "cases"), new NIRCVitalsFormSection(true, "cases"), diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCClinicalObservationsFormSection.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCClinicalObservationsFormSection.java index 3288e52a..b1e9ed3e 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCClinicalObservationsFormSection.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCClinicalObservationsFormSection.java @@ -22,13 +22,13 @@ public class NIRCClinicalObservationsFormSection extends BaseFormSection { public static final String LABEL = "Observations"; - private boolean _autoPopulateDailyObs; + private final String _dailyObsOption; - public NIRCClinicalObservationsFormSection(boolean autoPopulateDailyObs, boolean initCollapsed) + public NIRCClinicalObservationsFormSection(String dailyObsOption, boolean initCollapsed) { super("study", "clinical_observations", LABEL, "ehr-clinicalobservationgridpanel", true, initCollapsed, true); - _autoPopulateDailyObs = autoPopulateDailyObs; + _dailyObsOption = dailyObsOption; addClientDependency(ClientDependency.supplierFromPath("ehr/plugin/ClinicalObservationsCellEditing.js")); addClientDependency(ClientDependency.supplierFromPath("nirc_ehr/data/ClinicalObservationClientStore.js")); addClientDependency(ClientDependency.supplierFromPath("ehr/grid/ClinicalObservationGridPanel.js")); @@ -37,9 +37,9 @@ public NIRCClinicalObservationsFormSection(boolean autoPopulateDailyObs, boolean setClientStoreClass("NIRC_EHR.data.ClinicalObservationsClientStore"); } - public NIRCClinicalObservationsFormSection(boolean isChild, String parentQueryName) + public NIRCClinicalObservationsFormSection(String dailyObsOption, boolean isChild, String parentQueryName) { - this(false, true); + this(dailyObsOption, true); if (isChild && null != parentQueryName) { @@ -57,12 +57,9 @@ public List getTbarButtons() { List defaults = super.getTbarButtons(); - if (_autoPopulateDailyObs) + if (_dailyObsOption != null) { - defaults.add("NIRC_AUTO_POPULATE_DAILY_OBS"); - } - else { - defaults.add("NIRC_DAILY_CLINICAL_OBS"); + defaults.add(_dailyObsOption); } return defaults; diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/query/NIRC_EHRTriggerHelper.java b/nirc_ehr/src/org/labkey/nirc_ehr/query/NIRC_EHRTriggerHelper.java index 773a9b03..4342b1c4 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/query/NIRC_EHRTriggerHelper.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/query/NIRC_EHRTriggerHelper.java @@ -83,6 +83,7 @@ public class NIRC_EHRTriggerHelper private User _user; private static final Logger _log = LogManager.getLogger(NIRC_EHRTriggerHelper.class); private final Map _cachedDrugFormulary = new HashMap<>(); + private final Map _cachedObservationTypeCategories = new HashMap<>(); // Maps an originating observation order's taskid to the task its scheduled observations are grouped under, // for the duration of a single save batch (the same helper instance is reused across rows in the batch). @@ -810,6 +811,26 @@ public void ensureDailyClinicalObservationOrders(String id, String caseid, final } } + /** + * Returns the category of an observation type from ehr.observation_types, or null when the type has no + * category or is not found. Cached for the life of the save batch. + */ + public String getObservationTypeCategory(String observationType) + { + if (observationType == null) + return null; + + if (!_cachedObservationTypeCategories.containsKey(observationType)) + { + TableInfo ti = getTableInfo("ehr", "observation_types"); + SimpleFilter filter = new SimpleFilter(FieldKey.fromString("value"), observationType); + List categories = new TableSelector(ti, Collections.singleton("category"), filter, null).getArrayList(String.class); + _cachedObservationTypeCategories.put(observationType, categories.isEmpty() ? null : categories.get(0)); + } + + return _cachedObservationTypeCategories.get(observationType); + } + // This helper function propagates clinical observations through clinical cases public Map handleScheduledObservations(Map row, String qcstate, String orderTasks) throws SQLException, BatchValidationException, QueryUpdateServiceException, DuplicateKeyException {