From 89f4021444381a02ab5ddadb394a008792607213 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Wed, 11 Feb 2026 08:55:43 -0800 Subject: [PATCH 1/6] Rearrival --- nirc_ehr/resources/queries/study/arrival.js | 18 +++--- .../resources/queries/study/arrival.query.xml | 3 + .../queries/study/arrival/.qview.xml | 5 +- .../queries/study/protocolAssignment.js | 8 +-- .../study/datasets/datasets_metadata.xml | 3 + nirc_ehr/resources/scripts/nirc_triggers.js | 19 ++++++- .../web/nirc_ehr/model/sources/Arrival.js | 5 ++ .../web/nirc_ehr/model/sources/Rearrival.js | 57 +++++++++++++++++++ .../org/labkey/nirc_ehr/NIRC_EHRModule.java | 1 + .../dataentry/form/NIRCRearrivalFormType.java | 45 +++++++++++++++ .../section/NIRCRearrivalFormSection.java | 20 +++++++ 11 files changed, 162 insertions(+), 22 deletions(-) create mode 100644 nirc_ehr/resources/web/nirc_ehr/model/sources/Rearrival.js create mode 100644 nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java create mode 100644 nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCRearrivalFormSection.java diff --git a/nirc_ehr/resources/queries/study/arrival.js b/nirc_ehr/resources/queries/study/arrival.js index 3eccf2fd..114c2a1c 100644 --- a/nirc_ehr/resources/queries/study/arrival.js +++ b/nirc_ehr/resources/queries/study/arrival.js @@ -2,19 +2,15 @@ require("ehr/triggers").initScript(this); var triggerHelper = new org.labkey.nirc_ehr.query.NIRC_EHRTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); -function onInit(event, helper){ - helper.setScriptOptions({ - allowAnyId: true, - requiresStatusRecalc: true, - allowDatesInDistantPast: true, - skipAssignmentCheck: true, - }); -} - EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'Arrival', function(helper, scriptErrors, row, oldRow) { + console.log('isRearrival:', row.rearrival); + if(!row.rearrival){ + helper.setScriptOptions({requiresStatusRecalc: true}); + } + // Due to order of operation, this needs to be done in upsert instead of insert - if (helper.getEvent() == 'insert' && row.Id && triggerHelper.animalIdExists(row.Id)) { + if (!row.rearrival && helper.getEvent() == 'insert' && row.Id && triggerHelper.animalIdExists(row.Id)) { EHR.Server.Utils.addError(scriptErrors, 'Id', 'Animal Id ' + row.Id + ' is already in use. Please use a different Id.', 'ERROR'); } @@ -25,7 +21,7 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even helper.registerArrival(row.Id, row.date); //Insert or update demographic and birth records - if (!helper.isETL() && !helper.isGeneratedByServer() && !helper.isValidateOnly()) { + if (!row.rearrival && !helper.isETL() && !helper.isGeneratedByServer() && !helper.isValidateOnly()) { // this allows demographic records in qcstates other than completed var extraDemographicsFieldMappings = { diff --git a/nirc_ehr/resources/queries/study/arrival.query.xml b/nirc_ehr/resources/queries/study/arrival.query.xml index 1d70cffe..ffe21086 100644 --- a/nirc_ehr/resources/queries/study/arrival.query.xml +++ b/nirc_ehr/resources/queries/study/arrival.query.xml @@ -69,6 +69,9 @@ meaning + + Rearrival + diff --git a/nirc_ehr/resources/queries/study/arrival/.qview.xml b/nirc_ehr/resources/queries/study/arrival/.qview.xml index 81c4e233..9aa2dd42 100644 --- a/nirc_ehr/resources/queries/study/arrival/.qview.xml +++ b/nirc_ehr/resources/queries/study/arrival/.qview.xml @@ -5,15 +5,14 @@ - - + + - \ No newline at end of file diff --git a/nirc_ehr/resources/queries/study/protocolAssignment.js b/nirc_ehr/resources/queries/study/protocolAssignment.js index 6f505272..c0429b50 100644 --- a/nirc_ehr/resources/queries/study/protocolAssignment.js +++ b/nirc_ehr/resources/queries/study/protocolAssignment.js @@ -6,7 +6,6 @@ var prevDate; var missing = []; var count = 0; -let animalIds = []; var triggerHelper = new org.labkey.nirc_ehr.query.NIRC_EHRTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); @@ -31,12 +30,7 @@ function getLastAssignment(id){ } function onInit(event, helper){ - - helper.setScriptOptions({ - allowAnyId: false, - requiresStatusRecalc: true, - allowDatesInDistantPast: true - }); + if (helper.isETL()) { LABKEY.Query.selectRows({ schemaName: 'ehr', diff --git a/nirc_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml b/nirc_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml index bc4e8f73..f8d49b0e 100644 --- a/nirc_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml +++ b/nirc_ehr/resources/referenceStudy/study/datasets/datasets_metadata.xml @@ -108,6 +108,9 @@ varchar + + boolean + diff --git a/nirc_ehr/resources/scripts/nirc_triggers.js b/nirc_ehr/resources/scripts/nirc_triggers.js index 3e90d1ea..ca94b556 100644 --- a/nirc_ehr/resources/scripts/nirc_triggers.js +++ b/nirc_ehr/resources/scripts/nirc_triggers.js @@ -26,10 +26,27 @@ exports.init = function (EHR) { }); }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'arrival', function(event, helper) { + helper.setScriptOptions({ + allowAnyId: true, + requiresStatusRecalc: false, // set in upsert to handle rearrival + allowDatesInDistantPast: true, + skipAssignmentCheck: true, + }); + }); + + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'protocolAssignment', function(event, helper) { + helper.setScriptOptions({ + allowAnyId: false, + requiresStatusRecalc: false, + allowDatesInDistantPast: true + }); + }); + EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'assignment', function(event, helper) { helper.setScriptOptions({ allowAnyId: false, - requiresStatusRecalc: true, + requiresStatusRecalc: false, allowDatesInDistantPast: true, skipAssignmentCheck: true, removeTimeFromDate: false, diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/Arrival.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/Arrival.js index 4fbabbe7..4586e7fe 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/Arrival.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/Arrival.js @@ -97,6 +97,11 @@ EHR.model.DataModelManager.registerMetadata('Arrival', { columnConfig: { width: 200 } + }, + rearrival: { + allowBlank: true, + hidden: true, + showInGrid: false } } } diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/Rearrival.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/Rearrival.js new file mode 100644 index 00000000..99600f02 --- /dev/null +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/Rearrival.js @@ -0,0 +1,57 @@ + +EHR.model.DataModelManager.registerMetadata('Rearrival', { + + byQuery: { + 'study.arrival': { + rearrival: { + getInitialValue: function (v, rec) { + return true + }, + editable: false, + hidden: true, + columnConfig: { + editable: false + } + }, + performedby: { + hidden: true, + showInGrid: false + }, + sourceFacility: { + allowBlank: false, + columnConfig: { + fixed: true, + width: 150 + }, + }, + acquisitionType: { + allowBlank: false, + columnConfig: { + fixed: true, + width: 150 + }, + }, + arrivalType: { + allowBlank: false, + columnConfig: { + width: 200 + } + }, + 'cage': { + allowBlank: true, + hidden: true, + showInGrid: false + }, + project: { + allowBlank: true, + hidden: true, + showInGrid: false + }, + arrivalProtocol: { + allowBlank: true, + hidden: true, + showInGrid: false + }, + } + } +}); \ No newline at end of file diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/NIRC_EHRModule.java b/nirc_ehr/src/org/labkey/nirc_ehr/NIRC_EHRModule.java index f2413357..59dac4c5 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/NIRC_EHRModule.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/NIRC_EHRModule.java @@ -236,6 +236,7 @@ private void registerDataEntry() EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NIRCBehaviorRoundsFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NIRCChemistryImportFormType.class, this)); EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NIRCSerologyImportFormType.class, this)); + EHRService.get().registerFormType(new DefaultDataEntryFormFactory(NIRCRearrivalFormType.class, this)); } @Override diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java new file mode 100644 index 00000000..3bc51d94 --- /dev/null +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java @@ -0,0 +1,45 @@ +package org.labkey.nirc_ehr.dataentry.form; + +import org.labkey.api.ehr.dataentry.DataEntryFormContext; +import org.labkey.api.ehr.dataentry.FormSection; +import org.labkey.api.ehr.dataentry.forms.LockAnimalsFormSection; +import org.labkey.api.module.Module; +import org.labkey.api.security.permissions.AdminPermission; +import org.labkey.api.view.template.ClientDependency; +import org.labkey.nirc_ehr.dataentry.section.NIRCAnimalDetailsFormSection; +import org.labkey.nirc_ehr.dataentry.section.NIRCArrivalInstructionsFormSection; +import org.labkey.nirc_ehr.dataentry.section.NIRCRearrivalFormSection; +import org.labkey.nirc_ehr.dataentry.section.NIRCTaskFormSection; + +import java.util.Arrays; + +public class NIRCRearrivalFormType extends NIRCBaseTaskFormType +{ + public static final String NAME = "Rearrival"; + + public NIRCRearrivalFormType(DataEntryFormContext ctx, Module owner) + { + super(ctx, owner, NAME, "Rearrivals", "Colony Management", Arrays.asList( + new LockAnimalsFormSection(), + new NIRCArrivalInstructionsFormSection(), + new NIRCTaskFormSection(), + new NIRCAnimalDetailsFormSection(), + new NIRCRearrivalFormSection() + )); + + addClientDependency(ClientDependency.supplierFromPath("nirc_ehr/model/sources/Arrival.js")); + addClientDependency(ClientDependency.supplierFromPath("nirc_ehr/model/sources/Rearrival.js")); + + for (FormSection s : getFormSections()) + { + s.addConfigSource("Arrival"); + s.addConfigSource("Rearrival"); + } + } + + @Override + public boolean isAvailable() + { + return super.isAvailable() && getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class); + } +} diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCRearrivalFormSection.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCRearrivalFormSection.java new file mode 100644 index 00000000..17c7eed4 --- /dev/null +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/section/NIRCRearrivalFormSection.java @@ -0,0 +1,20 @@ +package org.labkey.nirc_ehr.dataentry.section; + +import org.json.JSONObject; +import org.labkey.api.ehr.dataentry.DataEntryFormContext; + +public class NIRCRearrivalFormSection extends BaseFormSection +{ + public NIRCRearrivalFormSection() + { + super("study", "arrival", "Rearrivals", "ehr-gridpanel", true, true, true); + } + + @Override + public JSONObject toJSON(DataEntryFormContext ctx, boolean includeFormElements) + { + JSONObject json = super.toJSON(ctx, includeFormElements); + json.put("dataDependentCollapseHeader", true); + return json; + } +} From fbde02ced327950db8563da24d7cd453e638461b Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Wed, 11 Feb 2026 08:56:18 -0800 Subject: [PATCH 2/6] Bulk performedby datatype fix --- nirc_ehr/resources/web/nirc_ehr/model/sources/NIRCDefault.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nirc_ehr/resources/web/nirc_ehr/model/sources/NIRCDefault.js b/nirc_ehr/resources/web/nirc_ehr/model/sources/NIRCDefault.js index eee4923b..87ff22d8 100644 --- a/nirc_ehr/resources/web/nirc_ehr/model/sources/NIRCDefault.js +++ b/nirc_ehr/resources/web/nirc_ehr/model/sources/NIRCDefault.js @@ -14,7 +14,7 @@ EHR.model.DataModelManager.registerMetadata('Default', { allowBlank: true, defaultValue: LABKEY.Security.currentUser.id, getInitialValue: function (v, rec) { - if (Number.isInteger(v)){ + if (Number.isInteger(Number(v))){ return v; } @@ -140,7 +140,7 @@ EHR.model.DataModelManager.registerMetadata('Default', { sort: 'Type,DisplayName' }, getInitialValue: function (v, rec) { - if (Number.isInteger(v)){ + if (Number.isInteger(Number(v))){ return v; } From 478c1b79a93fc120f386c027d5e73dcdc91808ae Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Thu, 12 Feb 2026 21:43:42 -0800 Subject: [PATCH 3/6] test fix --- .../test/src/org.labkey.test/tests.nirc_ehr/NIRC_EHRTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 bf824464..64ae07fd 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 @@ -877,7 +877,7 @@ public void testDeathNecropsyForm() throws IOException, CommandException scrollIntoView(Locator.linkContainingText("More Actions")); _ext4Helper.selectComboBoxItem("Physical Condition:", "Excellent"); _ext4Helper.selectComboBoxItem("Condition of Specimen:", "Fresh"); - _helper.setDataEntryField("accessionNumber", "123"); + _helper.getExt4FieldForFormSection("Necropsy", "Accession Number").setValue("123"); scrollIntoView(Locator.name("diagnosis")); _helper.setDataEntryField("identification", "Extra information"); _helper.setDataEntryField("grossAbnormalities", "Extra leg"); @@ -1357,4 +1357,4 @@ private void lockForm() log("Form is already unlocked"); } } -} \ No newline at end of file +} From c7866f1581a7d11f091149d65d0d91f2d6479cf7 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Fri, 13 Feb 2026 07:07:07 -0800 Subject: [PATCH 4/6] couple more waits --- .../src/org.labkey.test/tests.nirc_ehr/NIRC_EHRTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 64ae07fd..6c610abb 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 @@ -872,8 +872,9 @@ public void testDeathNecropsyForm() throws IOException, CommandException log("Entering Necropsy"); impersonate(NIRC_BASIC_SUBMITTER_VET_TECH); beginAt(url); - Ext4GridRef necropsy = _helper.getExt4GridForFormSection("Necropsy"); - necropsy.expand(); + _helper.getExt4GridForFormSection("Necropsy"); + waitForElement(Ext4Helper.Locators.ext4Button("Submit Necropsy for Review"), WAIT_FOR_PAGE); + waitForElement(Ext4Helper.Locators.formItemWithLabel("Performed By:"), WAIT_FOR_PAGE); scrollIntoView(Locator.linkContainingText("More Actions")); _ext4Helper.selectComboBoxItem("Physical Condition:", "Excellent"); _ext4Helper.selectComboBoxItem("Condition of Specimen:", "Fresh"); From 7f7561e31573756cac2ffdb2ae4f9205754aad58 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Fri, 13 Feb 2026 07:20:03 -0800 Subject: [PATCH 5/6] CR feedback --- nirc_ehr/resources/queries/study/arrival.js | 1 - .../labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/nirc_ehr/resources/queries/study/arrival.js b/nirc_ehr/resources/queries/study/arrival.js index 114c2a1c..5bf0b91b 100644 --- a/nirc_ehr/resources/queries/study/arrival.js +++ b/nirc_ehr/resources/queries/study/arrival.js @@ -4,7 +4,6 @@ var triggerHelper = new org.labkey.nirc_ehr.query.NIRC_EHRTriggerHelper(LABKEY.S EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_UPSERT, 'study', 'Arrival', function(helper, scriptErrors, row, oldRow) { - console.log('isRearrival:', row.rearrival); if(!row.rearrival){ helper.setScriptOptions({requiresStatusRecalc: true}); } diff --git a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java index 3bc51d94..4b9bd840 100644 --- a/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java +++ b/nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCRearrivalFormType.java @@ -27,12 +27,10 @@ public NIRCRearrivalFormType(DataEntryFormContext ctx, Module owner) new NIRCRearrivalFormSection() )); - addClientDependency(ClientDependency.supplierFromPath("nirc_ehr/model/sources/Arrival.js")); addClientDependency(ClientDependency.supplierFromPath("nirc_ehr/model/sources/Rearrival.js")); for (FormSection s : getFormSections()) { - s.addConfigSource("Arrival"); s.addConfigSource("Rearrival"); } } From a17fa1ab3f91739b627d8a5dba92fde71d330365 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Fri, 13 Feb 2026 08:26:11 -0800 Subject: [PATCH 6/6] Wait to ensure field populates. Fail fast if not. --- .../tests.nirc_ehr/NIRC_EHRTest.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) 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 6c610abb..d9e75277 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 @@ -878,11 +878,19 @@ public void testDeathNecropsyForm() throws IOException, CommandException scrollIntoView(Locator.linkContainingText("More Actions")); _ext4Helper.selectComboBoxItem("Physical Condition:", "Excellent"); _ext4Helper.selectComboBoxItem("Condition of Specimen:", "Fresh"); - _helper.getExt4FieldForFormSection("Necropsy", "Accession Number").setValue("123"); + Ext4FieldRef accessionNumber = _helper.getExt4FieldForFormSection("Necropsy", "Accession Number"); + accessionNumber.setValue("123"); + waitFor(() -> "123".equals(accessionNumber.getValue()), WAIT_FOR_JAVASCRIPT); scrollIntoView(Locator.name("diagnosis")); - _helper.setDataEntryField("identification", "Extra information"); - _helper.setDataEntryField("grossAbnormalities", "Extra leg"); - _helper.setDataEntryField("diagnosis", "Dead"); + Ext4FieldRef identification = _helper.getExt4FieldForFormSection("Necropsy", "Name/State/License no. (quarantine only)"); + identification.setValue("Extra information"); + waitFor(() -> "Extra information".equals(identification.getValue()), WAIT_FOR_JAVASCRIPT); + Ext4FieldRef grossAbnormalities = _helper.getExt4FieldForFormSection("Necropsy", "Gross Abnormalities"); + grossAbnormalities.setValue("Extra leg"); + waitFor(() -> "Extra leg".equals(grossAbnormalities.getValue()), WAIT_FOR_JAVASCRIPT); + Ext4FieldRef diagnosis = _helper.getExt4FieldForFormSection("Necropsy", "Diagnosis"); + diagnosis.setValue("Dead"); + waitFor(() -> "Dead".equals(diagnosis.getValue()), WAIT_FOR_JAVASCRIPT); _ext4Helper.selectComboBoxItem("Performed By:", NIRC_BASIC_SUBMITTER_NAME); log("Entering Tissue Disposition");