[bot] Fast-forward for 26.7.3 - #16
Merged
Merged
Conversation
## Rationale Scope the housing cage lookups to a single container so housing grids, and the queries built on them, keep working on a server with more than one EHR folder. The cage lookup is keyed by container and location together, but the room and days-in-room columns matched on location alone, so a second EHR folder defining the same cage location makes those subqueries match more than one row and the query returns a database error instead of results. Production installations run a single EHR folder per server, so the effect is limited to test and development environments where several EHR folders coexist. ## Related Pull Requests - LabKey/nircEHRModules, branch `26.7_fb_cage_container_scope` — the identical fix in the NIRC customizer. ## Changes - Scope every cage lookup behind the housing room and days-in-room columns to a single container, preferring the EHR study container and falling back to the current one when it is not configured. - Fix a null dereference that could occur while building the room sort field.
…#4) ## Rationale The Record Treatment link on study.treatment_order passed the order's start date as the scheduledDate URL parameter, so every treatment recorded through it carried the same scheduledDate regardless of which schedule slot was being recorded. The second recording against an order then tripped the duplicate-treatment trigger in study/drug.js ("A treatment has already been entered for this order for this date and time.") while the treatmentSchedule grid still showed the slot as unrecorded, since its status join compares the computed slot time against the stored scheduledDate. ## Related Pull Requests - LabKey/johnsHopkinsEHRModules#667 (same fix for jhu_ehr) - LabKey/nircEHRModules#730 (same fix for nirc_ehr) ## Changes - Extract the inline Record Treatment display column into TreatmentDisplayColumnFactory with an includeScheduledDate flag; emit scheduledDate only when set, ISO-formatted via DateUtil.formatIsoDateShortTime() instead of Date.toString(); add a null guard on category. - The treatment_order Record Treatment link no longer passes scheduledDate; new customizeTreatmentSchedule() adds a treatmentRecord link column to study.treatmentSchedule that passes the slot's date. - treatmentSchedule.sql: drop the t1.treatmentRecord passthrough column inherited from treatment_order. - treatmentSchedule.query.xml: apply the module customizer via javaCustomizer so the new column is added.
) ## Rationale Adds the fields and lookup codes needed to bulk load historical birth, arrival and conception records into the NBRI EHR. The legacy source system keys its source, species and pregnancy-outcome lookups by short alpha codes rather than the numeric placeholders the module was seeded with, so those lookups have to be recoded before incoming values will resolve. The historical records also predate several of the required-field rules on the current entry forms. ## Changes - Add birth condition, delivery mode and breeding type to the birth record, and an estimated-date flag to conception. - Recode the source, species and pregnancy outcome lookups to the alpha codes used by the source system, and point the arrival and departure lookups at them. - Surface the task and status columns on the conception grid, with the standard status highlighting, and report a conception's offspring alongside its outcome. - Add a Start with Conception action to the birth form that seeds a new birth record from an existing conception, inferring the newborn's species from the dam. - Move project and protocol entry on the arrival and birth forms into dedicated assignment sections, which relaxes animal Id validation for animals that have no demographics record yet. - Relax required-field validation on the arrival and birth entry forms so historical records can be loaded. These rules are left in place as commented-out code so they can be restored once the loads are done. - The conception estimated-date flag is added to the in-flight 26.7 schema script rather than a new one, so servers that already ran it need a bootstrap.
…#11) ## Rationale Historical deaths have to be loaded for the colony, and the existing Death/Necropsy form takes one animal at a time and requires necropsy data alongside the death. This adds an admin-only grid form that records deaths only, and hardens `study/deaths.js` for the multi-row saves that form produces: the duplicate checks dereferenced values that are null for an animal with no prior death record, and a second row for one animal reached the unique constraint on this demographic dataset and surfaced as a database error rather than a validation message. ## Changes - `NBRIBulkDeathFormType`, an admin-only grid form for entering completed historical deaths in bulk, with `Death.js` supplying its grid metadata. - A `type` (Death Type) column on `study.deaths`, backed by a new `ehr_lookups.death_type` lookup of the 13 codes the source data uses. `A` and `X` share the title `Experimental`, so only the code round-trips reliably on import. `DeathNecropsy.js` now requires `type` rather than `reason`, and `deathWeight` becomes optional — not every historical death carries a weight. - `study/deaths.js`: null-safe duplicate checks; a second row for an animal is reported as a validation error, both against the pre-save snapshot and against a helper property tracking animals saved earlier in the same transaction; an Id absent from demographics is now rejected on insert; the weight upsert moved into the success branch and gated on `!isValidateOnly`; removed the dead `validIds` check. - `NBRI_EHRTriggerHelper.upsertWeightRecord` returns whether a row was written and gains an `announceChanges` overload, so a caller writing many weight rows in one transaction suppresses the per-row participant announcement and announces once via `addTableModified`. With no weight entered it deletes any record left by an earlier save rather than blanking it — the weight trigger only WARNs on a null weight and the default threshold filters that, so an emptied record would otherwise survive the save. - The existing-weight lookup is skipped when `taskid` is null, making task-less entry insert-only. A null `taskid` filter flips to `taskid IS NULL` and would match unrelated historical weights for the animal. - `study.departure.destination` resolves through the lookup's `code` column instead of `meaning`, matching how the values are stored. - Removed a stray apostrophe that left `study.aliases` unparseable. - `NBRI_EHRTest` covers the unknown-Id and existing-record rejections in the Death form and asserts through the API that a second death insert returns a validation error rather than a constraint violation.
## Rationale This PR sets up NBRI weight and species reporting. Weight validation never fired, because the weight ranges lookup was keyed on species common names while demographics records hold species codes, so no animal ever matched a range. NBRI's query metadata files also replace the ehr module's rather than merging with them, so several wrapped lookup columns that the ehr-supplied views depend on had silently disappeared from NBRI tables. ## Changes - Key the weight ranges on species codes, and load the species lookups those codes resolve against. - Re-declare the wrapped lookup columns that NBRI's query metadata was dropping so the ehr-supplied views resolve again, and correct a metadata file that named the wrong table. - Convert the test subjects and the reference sample data from placeholder species and sex values to real lookup codes, and update the weight validation expectation to match the new ranges.
## Rationale Animal record flags were displayed by their short value, which is a terse code rather than something a reader can interpret, so the descriptive text already stored alongside each flag went unused. The flag lookup also keyed on an opaque identifier, which made the underlying data hard to read and maintain. ## Changes - The flags lookup is keyed and displayed by meaningful text rather than an opaque identifier, so flags read as category plus description wherever they appear. - The animal snapshot, the flags data entry form, and the default flags grid all show the description. - Flag categories and values are seeded as module lookups. - Flag records may be future dated. - Sample data references flags by their value.
## Rationale Remove floors from the NBRI location hierarchy so a location is identified by building, room, and cage alone. Floors are not a meaningful unit of location at NBRI, and requiring one on every room forced entry of a value that carries no information while complicating the derived location keys. This also drops the historicalOther dataset, which is no longer part of the reference study. Keys are derived only when a record is created, so nothing recomputes them for locations that already exist. There is no location data in place yet, so there is nothing to migrate. ## Changes - Rooms are keyed by building and name, and floor is no longer required or shown. Room entry now requires a building, since the derived key depends on it. - Buildings no longer fold the area into their name, so a description identifies a building on its own and a reused one is rejected rather than colliding. - Derived building, room, and cage keys are persisted consistently, and a key too long for its column is rejected with a message naming the parts at fault. Cages resolve to their room. - The cagemates report resolves animals in group pens, which have no cage and are housed against the room alone. Animals with a cage continue to match on the cage, which already identifies its room. - The cagemates report now counts only current occupants. It previously counted every living animal that had ever been housed in the cage, and it now also skips housing records that have not been approved. - Removes the floor-based combined room and floor display columns, and repoints everything that depended on them: the room and floor lookups, the housing views and history, the cage details page, and every view that previously reached the building through a floor. - Room lookups carry a link through to the cage details page, matching how cages already behave. - Location test fixtures build rooms from a building instead of a floor, and cover the room key, the building rules, and cagemates for both group pens and cages recorded without a room. - Removes the historicalOther dataset, its report, and its metadata.
labkey-klum
approved these changes
Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Generated automatically.
Approve all matching PRs simultaneously.
Approval will trigger automatic merge.
View all PRs: https://internal.labkey.com/Scrumtime/Backlog/harvest-gitOpenPullRequests.view?branch=26.7_ff_bot_26.7.3