From 6d13aa3658628e2ead40ec6829d8b101a46c9cd4 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Sun, 30 Aug 2026 17:54:45 -0600 Subject: [PATCH 1/6] Send the death notification on the first non-draft save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The notification and procedure-order update only fired when the record landed on 'Request: Pending', so a death entered alongside its necropsy — which goes straight to 'Review Required' or 'Completed' — never triggered either. --- nirc_ehr/resources/queries/study/deaths.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/nirc_ehr/resources/queries/study/deaths.js b/nirc_ehr/resources/queries/study/deaths.js index 9e1133f1..904b2073 100644 --- a/nirc_ehr/resources/queries/study/deaths.js +++ b/nirc_ehr/resources/queries/study/deaths.js @@ -172,14 +172,12 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even var row = rows[i].row; var oldRow = rows[i].oldRow; - // Notification will get sent when: - // 1) a brand-new row saved directly as 'Request: Pending' (i.e., when a user clicks 'Submit Death'), or - // 2) a draft death record moving from 'In Progress' to 'Request: Pending'. - if (!helper.isETL() && - row && row.Id && - row.QCStateLabel && - row.QCStateLabel.toUpperCase() === 'REQUEST: PENDING' && - (!oldRow || !oldRow.QCStateLabel || oldRow.QCStateLabel.toUpperCase() === 'IN PROGRESS')) { + if (helper.isETL() || !row || !row.Id || !row.QCStateLabel) + continue; + + // Notify once, on the first non-draft save: 'Submit Death' lands on 'Request: Pending', but a death entered alongside its necropsy goes straight to 'Review Required' or 'Completed'. + var wasDraft = !oldRow || !oldRow.QCStateLabel || oldRow.QCStateLabel.toUpperCase() === 'IN PROGRESS'; + if (wasDraft && row.QCStateLabel.toUpperCase() !== 'IN PROGRESS') { console.log("Sending NIRC Death Notification") triggerHelper.sendDeathNotification(row.Id); From 672e93e9a09872d9d7ee1355bf1711b9fe221245 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Sun, 30 Aug 2026 19:07:04 -0600 Subject: [PATCH 2/6] Format birth and arrival dates as date-time so entry keeps the time The EHR data-entry framework only offers a time-of-day editor when the column's display format contains hour information, so both forms were storing every event at midnight. --- nirc_ehr/resources/queries/study/arrival.query.xml | 1 + nirc_ehr/resources/queries/study/birth.query.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/nirc_ehr/resources/queries/study/arrival.query.xml b/nirc_ehr/resources/queries/study/arrival.query.xml index ffe21086..3b8933b1 100644 --- a/nirc_ehr/resources/queries/study/arrival.query.xml +++ b/nirc_ehr/resources/queries/study/arrival.query.xml @@ -11,6 +11,7 @@ Arrival Date + DateTime Arrival Type diff --git a/nirc_ehr/resources/queries/study/birth.query.xml b/nirc_ehr/resources/queries/study/birth.query.xml index 40849889..ea501cee 100644 --- a/nirc_ehr/resources/queries/study/birth.query.xml +++ b/nirc_ehr/resources/queries/study/birth.query.xml @@ -12,6 +12,7 @@ Birth Date + DateTime Birth Location From 0af54d07db9ba14eb7e3ce5a8a02a2a5ba29c271 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Sun, 30 Aug 2026 21:23:14 -0600 Subject: [PATCH 3/6] Stop stripping the time from birth dates The birth trigger set the EHR removeTimeFromDate script option, so every birth date and the assignment, protocol assignment, and housing records derived from it were saved at midnight. --- nirc_ehr/resources/queries/study/birth.js | 1 - 1 file changed, 1 deletion(-) diff --git a/nirc_ehr/resources/queries/study/birth.js b/nirc_ehr/resources/queries/study/birth.js index 26b5e66a..66b4e9a2 100644 --- a/nirc_ehr/resources/queries/study/birth.js +++ b/nirc_ehr/resources/queries/study/birth.js @@ -17,7 +17,6 @@ function onInit(event, helper){ skipHousingCheck: true, announceAllModifiedParticipants: true, allowDatesInDistantPast: true, - removeTimeFromDate: true, skipAssignmentCheck: true, }); From f70d6672e22860760d771bf943a26fea4494eeb0 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Sun, 30 Aug 2026 21:39:32 -0600 Subject: [PATCH 4/6] Fix duplicate Assign To dropdown in the Submit For Review window The combo claimed a page-wide element name and Cancel only hid the window rather than discarding it, so reopening the dialog rendered the previous window's field alongside the new one. --- .../resources/web/nirc_ehr/buttons/deathNecropsyButtons.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js b/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js index 344873ff..9cfd54cc 100644 --- a/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js +++ b/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js @@ -101,7 +101,7 @@ Ext4.define('NIRC_EHR.window.DeathNecropsySubmitForReviewWindow', { text: 'Cancel', scope: this, handler: function(btn){ - btn.up('window').hide(); + btn.up('window').close(); } }], items: [{ @@ -127,8 +127,8 @@ Ext4.define('NIRC_EHR.window.DeathNecropsySubmitForReviewWindow', { value: this.getDefaultRecipient(), displayField: 'DisplayName', valueField: 'UserId', + // No global 'id' here: a reopened window would adopt the previous window's element and render a second combo. itemId: 'assignedTo', - id: 'assignedTo', anyMatch: true, caseSensitive: false, }] From 55208ea10f5f5aa5050e86221334ff8dea543463 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Mon, 31 Aug 2026 06:18:24 -0600 Subject: [PATCH 5/6] Skip the death notification on delete events A delete reaches the COMPLETE handler as the deleted row with a null oldRow, which read as a draft leaving draft and re-ran the notification and the procedure-order update. --- nirc_ehr/resources/queries/study/deaths.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nirc_ehr/resources/queries/study/deaths.js b/nirc_ehr/resources/queries/study/deaths.js index 904b2073..8695ed58 100644 --- a/nirc_ehr/resources/queries/study/deaths.js +++ b/nirc_ehr/resources/queries/study/deaths.js @@ -167,6 +167,10 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even }); EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.COMPLETE, 'study', 'Deaths', function(event, errors, helper){ + // A delete arrives here as the deleted row with a null oldRow, which otherwise reads as a draft leaving draft. + if (event === 'delete') + return; + var rows = helper.getRows() || []; for (var i = 0; i < rows.length; i++) { var row = rows[i].row; From 6499c6e1473de218821fba092ec9989d71af0576 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Mon, 31 Aug 2026 06:19:13 -0600 Subject: [PATCH 6/6] Give the Assign To combo an explicit field name Ext derives the input name from the component id, so dropping the global id renamed the input and broke the locator testDeathNecropsyForm uses to find it. --- nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js b/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js index 9cfd54cc..cd8f4f2d 100644 --- a/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js +++ b/nirc_ehr/resources/web/nirc_ehr/buttons/deathNecropsyButtons.js @@ -129,6 +129,8 @@ Ext4.define('NIRC_EHR.window.DeathNecropsySubmitForReviewWindow', { valueField: 'UserId', // No global 'id' here: a reopened window would adopt the previous window's element and render a second combo. itemId: 'assignedTo', + // Ext derives the input's name from the component id when 'name' is absent, so set it explicitly rather than leaning on the id. + name: 'assignedTo', anyMatch: true, caseSensitive: false, }]