diff --git a/nirc_ehr/resources/data/amount_units.tsv b/nirc_ehr/resources/data/amount_units.tsv index 4b8451e7..880b2731 100644 --- a/nirc_ehr/resources/data/amount_units.tsv +++ b/nirc_ehr/resources/data/amount_units.tsv @@ -1,9 +1,14 @@ Unit g +gummy IU +mcg mEq mg +mL no units ounces +scoop +tablet ug units diff --git a/nirc_ehr/resources/data/conc_units.tsv b/nirc_ehr/resources/data/conc_units.tsv index 176cca6b..eb6660f3 100644 --- a/nirc_ehr/resources/data/conc_units.tsv +++ b/nirc_ehr/resources/data/conc_units.tsv @@ -1,12 +1,18 @@ Unit Denominator Numerator +g/gummy gummy g g/mL mL g +g/tablet tablet g g/tsp tsp g -IU/ml mL IU -mEq/ml mL mEq +IU/mL mL IU +mcg/mL mL mcg +mEq/mL mL mEq mg/capsule capsule(s) mg -mg/ml mL mg +mg/implant implant mg +mg/kg kg mg +mg/mL mL mg mg/piece piece(s) mg mg/tablet tablet(s) mg mg/tsp tsp mg -ug/ml mL ug -units/ml mL units +mL/kg kg mL +ug/mL mL ug +units/mL mL units diff --git a/nirc_ehr/resources/data/dosage_units.tsv b/nirc_ehr/resources/data/dosage_units.tsv index cf779f18..66cb1ef2 100644 --- a/nirc_ehr/resources/data/dosage_units.tsv +++ b/nirc_ehr/resources/data/dosage_units.tsv @@ -1,10 +1,13 @@ Unit Numerator Denominator +1/8 scoop/kg 1/8 scoop kg g/kg g kg IU/kg IU kg +mcg/kg mcg kg mEq/kg mEq kg +mg mg/animal mg animal mg/kg mg kg -ml/kg ml kg +mL/kg ml kg no units ounces/kg ounces kg ug/kg ug kg diff --git a/nirc_ehr/resources/data/volume_units.tsv b/nirc_ehr/resources/data/volume_units.tsv index 336ca872..6f20a8ce 100644 --- a/nirc_ehr/resources/data/volume_units.tsv +++ b/nirc_ehr/resources/data/volume_units.tsv @@ -1,10 +1,16 @@ Unit +capsule capsule(s) cup drop(s) +gummy +implant +mg mL no units ounce(s) piece(s) +scoop +tablet tablet(s) tsp diff --git a/nirc_ehr/resources/queries/study/cases.js b/nirc_ehr/resources/queries/study/cases.js index 02e895b3..34a1fa2d 100644 --- a/nirc_ehr/resources/queries/study/cases.js +++ b/nirc_ehr/resources/queries/study/cases.js @@ -15,8 +15,14 @@ function onInit(event, helper) { EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'cases', function(helper, errors, row, oldRow){ if (!helper.isETL()) { - if (row.enddate && !triggerHelper.canCloseCase(row.category)) { + if (row.enddate) { + if (!row.closeRemark) { + EHR.Server.Utils.addError(errors, 'closeRemark', 'Close remark required when closing a case.', 'ERROR'); + } + + if(!triggerHelper.canCloseCase(row.category)) { EHR.Server.Utils.addError(errors, 'enddate', 'Veterinarian permission required to close a case.', 'ERROR'); + } } if (!helper.isValidateOnly() && row.caseid && row.enddate && (row.enddate != oldRow.enddate)) { diff --git a/nirc_ehr/resources/views/animalHistory.html b/nirc_ehr/resources/views/animalHistory.html index c1bebcee..2e04db93 100644 --- a/nirc_ehr/resources/views/animalHistory.html +++ b/nirc_ehr/resources/views/animalHistory.html @@ -12,6 +12,7 @@ showFilterOptionsTitle: true, showReportsOption:true, caseInsensitiveSubjects: true, + reportQCStates: ['Completed', 'Review Required', 'Abnormal'], filterTypes: [{ xtype: 'ldk-singlesubjectfiltertype', inputValue: LDK.panel.SingleSubjectFilterType.filterName, diff --git a/nirc_ehr/resources/web/nirc_ehr/buttons/SelectCaseButton.js b/nirc_ehr/resources/web/nirc_ehr/buttons/SelectCaseButton.js index af751156..4e136114 100644 --- a/nirc_ehr/resources/web/nirc_ehr/buttons/SelectCaseButton.js +++ b/nirc_ehr/resources/web/nirc_ehr/buttons/SelectCaseButton.js @@ -36,8 +36,8 @@ Ext4.define('NIRC_EHR.form.field.SelectCaseButton', { if (taskid) { let record = EHR.DataEntryUtils.getBoundRecord(this.up('panel')); if (!record || !record.get('Id')) { - let clinRemarksPanel = this.up('#upperPanel')?.query('ehr-formpanel')?.find(panel => panel.formConfig.name === 'clinremarks'); - let caseid = clinRemarksPanel?.store?.data?.get(0)?.get('caseid'); + let tasksPanel = this.up('#upperPanel')?.query('ehr-formpanel')?.find(panel => panel.formConfig.name === 'tasks'); + let caseid = tasksPanel?.store?.data?.get(0)?.get('caseid'); if (caseid) { this.handleCaseSelect(caseid, false); } diff --git a/nirc_ehr/resources/web/nirc_ehr/buttons/treatmentSubmit.js b/nirc_ehr/resources/web/nirc_ehr/buttons/treatmentSubmit.js index 1c9c605c..a6e1baf1 100644 --- a/nirc_ehr/resources/web/nirc_ehr/buttons/treatmentSubmit.js +++ b/nirc_ehr/resources/web/nirc_ehr/buttons/treatmentSubmit.js @@ -9,11 +9,83 @@ EHR.DataEntryUtils.registerDataEntryFormButton('NIRC_TREATMENT_SUBMIT', { disabled: true, itemId: 'submitBtn', handler: function(btn){ - var panel = btn.up('ehr-dataentrypanel'); - Ext4.Msg.confirm('Finalize Form', 'You are about to finalize this form. Do you want to do this?', function(v){ - if(v == 'yes') - this.onSubmit(btn); - }, this); + + const panel = btn.up('ehr-dataentrypanel'); + const casesStore = panel?.storeCollection?.getClientStoreByName('cases'); + if (casesStore) { + const rec = casesStore.getAt(0); + const caseid = casesStore.getAt(0).get('caseid'); + if (!caseid) { // only check for new cases + const id = rec.get('Id'); + const problemCategory = rec.get('problemCategory'); + const category = rec.get('category'); + if (id && problemCategory && category) { + const filters = [ + LABKEY.Filter.create('Id', id), + LABKEY.Filter.create('category', category), + LABKEY.Filter.create('problemCategory', problemCategory), + LABKEY.Filter.create('isActive', true), + LABKEY.Filter.create('QCState/Label', "Completed", LABKEY.Filter.Types.EQUAL) + ] + const caseid = rec.get('caseid'); + if (caseid) { + filters.push(LABKEY.Filter.create('caseid', caseid, LABKEY.Filter.Types.NEQ)) + } + LABKEY.Query.selectRows({ + schemaName: 'study', + queryName: 'cases', + filterArray: filters, + columns: 'problemSubcategory', + scope: this, + failure: LDK.Utils.getErrorCallback(), + success: function (results) { + if (results.rows.length > 0) { + const subcategories = []; + for (let i = 0; i < results.rows.length; i++) { + subcategories.push(results.rows[i].problemSubcategory); + } + let msg; + if (subcategories.length === 1) { + msg = 'This animal already has a case with the problem ' + problemCategory + '. The subcategory is ' + results.rows[0].problemSubcategory + '. Do you still want to submit this case?'; + } + else { + msg = 'This animal already has ' + subcategories.length + ' cases with the problem ' + problemCategory + '. The subcategories are ' + subcategories.join(', ') + '. Do you still want to submit this case?'; + } + + Ext4.Msg.confirm('Similar Case Exists', msg, function (v) { + if (v == 'yes') + this.onSubmit(btn); + }, this); + } + else { + Ext4.Msg.confirm('Finalize Form', 'You are about to finalize this form. Do you want to do this?', function (v) { + if (v == 'yes') + this.onSubmit(btn); + }, this); + } + } + }); + } + else { + Ext4.Msg.confirm('Finalize Form', 'You are about to finalize this form. Do you want to do this?', function (v) { + if (v == 'yes') + this.onSubmit(btn); + }, this); + } + } + else { + Ext4.Msg.confirm('Finalize Form', 'You are about to finalize this form. Do you want to do this?', function (v) { + if (v == 'yes') + this.onSubmit(btn); + }, this); + } + } + else { + Ext4.Msg.confirm('Finalize Form', 'You are about to finalize this form. Do you want to do this?', function (v) { + if (v == 'yes') + this.onSubmit(btn); + }, this); + } }, listeners: { afterRender: function(btn){ diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/BehaviorDefaults.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/BehaviorDefaults.js index e4c9e53b..86ce572b 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/BehaviorDefaults.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/BehaviorDefaults.js @@ -73,15 +73,6 @@ EHR.model.DataModelManager.registerMetadata('BehaviorDefaults', { category: { defaultValue: 'Behavior', hidden: true - }, - scheduledDate: { - columnConfig: { - width: 130, - fixed: true - }, - }, - treatmentId: { - hidden: true } }, 'study.treatment_order': { diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/BehavioralCase.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/BehavioralCase.js index cbfc9710..948eb813 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/BehavioralCase.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/BehavioralCase.js @@ -57,6 +57,7 @@ EHR.model.DataModelManager.registerMetadata('BehavioralCase', { } }, problemCategory: { + nullable: false, editorConfig: { listeners: { select: function (field, recs) { diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalCase.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalCase.js index cd9c593c..29af7961 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalCase.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalCase.js @@ -57,6 +57,7 @@ EHR.model.DataModelManager.registerMetadata('ClinicalCase', { } }, problemCategory: { + nullable: false, editorConfig: { listeners: { select: function (field, recs) { diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalDefaults.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalDefaults.js index 4431592d..0e4f1217 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalDefaults.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/ClinicalDefaults.js @@ -53,6 +53,9 @@ EHR.model.DataModelManager.registerMetadata('ClinicalDefaults', { } }, procedure: { + lookup: { + filterArray: [LABKEY.Filter.create('active', true, LABKEY.Filter.Types.EQUAL)] + }, columnConfig: { width: 250 } @@ -63,15 +66,6 @@ EHR.model.DataModelManager.registerMetadata('ClinicalDefaults', { defaultValue: 'Clinical', hidden: true }, - scheduledDate: { - columnConfig: { - width: 130, - fixed: true - }, - }, - treatmentId: { - hidden: true - }, date: { header: 'Date/Time', } @@ -83,6 +77,9 @@ EHR.model.DataModelManager.registerMetadata('ClinicalDefaults', { }, // procedure data is not categorized, so not using procedure_category based selection procedure: { + lookup: { + filterArray: [LABKEY.Filter.create('active', true, LABKEY.Filter.Types.EQUAL)] + }, columnConfig: { width: 250 } 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 d2961313..3bab8808 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 @@ -12,10 +12,8 @@ import org.labkey.nirc_ehr.dataentry.section.NIRCCaseTemplateFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCCasesFormPanelSection; import org.labkey.nirc_ehr.dataentry.section.NIRCClinicalObservationsFormSection; -import org.labkey.nirc_ehr.dataentry.section.NIRCObservationOrdersFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCTaskFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCTreatmentGivenFormSection; -import org.labkey.nirc_ehr.dataentry.section.NIRCTreatmentOrderFormSection; import java.util.Arrays; import java.util.List; @@ -34,9 +32,7 @@ public NIRCBehaviorRoundsFormType(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 NIRCClinicalObservationsFormSection(true, "cases"), - new NIRCObservationOrdersFormSection(null, true, "cases"), - new NIRCTreatmentGivenFormSection(true, "cases"), - new NIRCTreatmentOrderFormSection(true, "cases") + new NIRCTreatmentGivenFormSection(true, "cases") )); setTemplateMode(AbstractFormSection.TEMPLATE_MODE.NO_ID); 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 7f74303b..bb3dd342 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 @@ -13,12 +13,9 @@ import org.labkey.nirc_ehr.dataentry.section.NIRCCasesFormPanelSection; import org.labkey.nirc_ehr.dataentry.section.NIRCClinicalObservationsFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCHousingFormSection; -import org.labkey.nirc_ehr.dataentry.section.NIRCObservationOrdersFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCProcedureFormSection; -import org.labkey.nirc_ehr.dataentry.section.NIRCProcedureOrderFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCTaskFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCTreatmentGivenFormSection; -import org.labkey.nirc_ehr.dataentry.section.NIRCTreatmentOrderFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCVitalsFormSection; import org.labkey.nirc_ehr.dataentry.section.NIRCWeightFormSection; @@ -39,12 +36,8 @@ public NIRCClinicalRoundsFormType(DataEntryFormContext ctx, Module owner) new NIRCCasesFormPanelSection("Clinical Case", ctx, false), new NIRCWeightFormSection(true, false, true, "cases"), new NIRCClinicalObservationsFormSection(true, "cases"), - new NIRCObservationOrdersFormSection(null, true, "cases"), new NIRCProcedureFormSection(true, "cases"), - new NIRCProcedureOrderFormSection(true, "cases"), new NIRCTreatmentGivenFormSection(true, "cases"), - new NIRCTreatmentOrderFormSection(true, - "cases"), new NIRCVitalsFormSection(true, "cases"), new NIRCBloodDrawFormSection(true, "cases"), new NIRCHousingFormSection(true, true, true, "cases") diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCCasesFormPanelSection.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCCasesFormPanelSection.java index 123dd755..6046b1a0 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCCasesFormPanelSection.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCCasesFormPanelSection.java @@ -61,6 +61,8 @@ protected List getFieldKeys(TableInfo ti) keys.remove(FieldKey.fromString("closeRemark")); } + keys.add(FieldKey.fromString("qcstate/label")); + return keys; } } diff --git a/nirc_ehr/test/src/org.labkey.test/tests.nirc_ehr/NIRC_EHRTest.java b/nirc_ehr/test/src/org.labkey.test/tests.nirc_ehr/NIRC_EHRTest.java index 7305c7c4..21a0620a 100644 --- a/nirc_ehr/test/src/org.labkey.test/tests.nirc_ehr/NIRC_EHRTest.java +++ b/nirc_ehr/test/src/org.labkey.test/tests.nirc_ehr/NIRC_EHRTest.java @@ -456,6 +456,9 @@ public void testClinicalObservation() waitAndClickAndWait(Locator.linkWithText("Clinical Cases")); //Fill out Clinical Case section with Id, Date, Open Remark + Ext4FieldRef problem = _helper.getExt4FieldForFormSection("Clinical Case", "Problem Area"); + problem.clickTrigger(); + problem.setValue("General abnormality"); _helper.setDataEntryField("openRemark", "Clinical Case WorkFlow - Test"); _helper.setDataEntryField("plan", "Case plan - Test"); _helper.getExt4FieldForFormSection("Clinical Case", "Open Date").setValue(LocalDateTime.now().minusDays(1).format(_dateFormat)); @@ -534,6 +537,8 @@ public void testClinicalObservation() waitForTextToDisappear("Subjective: WARN: Must enter at least one comment"); waitAndClick(Ext4Helper.Locators.ext4Button("Edit")); _helper.getExt4FieldForFormSection("Clinical Case", "Close Date").setValue(LocalDateTime.now().format(_dateFormat)); + _helper.setDataEntryField("closeRemark", "Case closed."); + submitForm("Submit Final", "Finalize"); goToEHRFolder(); @@ -799,6 +804,9 @@ public void testClinicalCasesWorkflow() waitAndClickAndWait(Locator.linkWithText("Clinical Cases")); //Fill out Clinical Case section with Id, Date, Open Remark + Ext4FieldRef problem = _helper.getExt4FieldForFormSection("Clinical Case", "Problem Area"); + problem.clickTrigger(); + problem.setValue("Circulatory abnormality"); setFormElement(Locator.textarea("openRemark"), "Clinical Case WorkFlow - Test"); setFormElement(Locator.textarea("plan"), "Case plan"); setFormElement(Locator.name("Id"), animalId); @@ -876,6 +884,10 @@ public void testClinicalCasesWorkflow() Ext4Helper.Locators.ext4Button("Edit").findElement(getDriver()).click(); //click again enddateField.setValue(LocalDateTime.now().minusDays(1).format(_dateFormat)); + // Verify close remark required + waitForText("Close remark required when closing a case."); + _helper.setDataEntryField("closeRemark", "Case closed."); + //'Submit Final' submitForm("Submit Final", "Finalize Form"); @@ -935,6 +947,10 @@ public void testBehavioralCases() gotoEnterData(); waitAndClickAndWait(Locator.linkWithText("Behavioral Cases")); waitForText("The field: Id is required"); + Ext4FieldRef problem = _helper.getExt4FieldForFormSection("Behavior Case", "Problem Area"); + problem.clickTrigger(); + problem.setValue("Behavioral"); + _helper.setDataEntryField("problemCategory", "Behavioral"); _helper.setDataEntryField("remark", "Behavioral case remarks"); _helper.getExt4FieldForFormSection("Behavior Case", "Open Date").setValue(LocalDateTime.now().minusDays(1).format(_dateFormat)); setFormElement(Locator.name("Id"), animalId1); @@ -966,6 +982,12 @@ public void testBehavioralCases() gotoEnterData(); waitAndClickAndWait(Locator.linkWithText("Behavioral Cases")); waitForText("The field: Id is required"); + + // Set case problem + problem = _helper.getExt4FieldForFormSection("Behavior Case", "Problem Area"); + problem.clickTrigger(); + problem.setValue("Behavioral"); + _helper.setDataEntryField("remark", "Behavioral case remarks "); _helper.getExt4FieldForFormSection("Behavior Case", "Open Date").setValue(LocalDateTime.now().minusDays(31).format(_dateFormat)); setFormElement(Locator.name("Id"), animalId2); @@ -1033,7 +1055,12 @@ public void testBehavioralCases() _helper.setDataEntryField("remark", "Closing the case"); waitForTextToDisappear("Subjective: WARN: Must enter at least one comment"); waitAndClick(Ext4Helper.Locators.ext4Button("Edit")); + + // Verify close remark required _helper.getExt4FieldForFormSection("Behavior Case", "Close Date").setValue(LocalDateTime.now().format(_dateFormat)); + waitForText("Close remark required when closing a case."); + _helper.setDataEntryField("closeRemark", "Case closed."); + submitForm("Submit Final", "Finalize"); goToEHRFolder();