diff --git a/nbri_ehr/resources/queries/study/Pedigree.sql b/nbri_ehr/resources/queries/study/Pedigree.sql index 331c8bd..159b370 100644 --- a/nbri_ehr/resources/queries/study/Pedigree.sql +++ b/nbri_ehr/resources/queries/study/Pedigree.sql @@ -6,8 +6,9 @@ SELECT d.id as Id, - d.dam as Dam, - d.sire as Sire, + -- UNKNOWN is a placeholder parent; passed through, kinship would treat every animal recorded against it as siblings + CASE WHEN UPPER(d.dam) = 'UNKNOWN' THEN NULL ELSE d.dam END as Dam, + CASE WHEN UPPER(d.sire) = 'UNKNOWN' THEN NULL ELSE d.sire END as Sire, d.modified, CASE (d.id.demographics.gender.meaning) @@ -28,4 +29,4 @@ SELECT d.modified FROM study.demographics d -WHERE d.Dam IS NOT NULL OR d.Sire IS NOT NULL +WHERE (d.Dam IS NOT NULL AND UPPER(d.Dam) <> 'UNKNOWN') OR (d.Sire IS NOT NULL AND UPPER(d.Sire) <> 'UNKNOWN') diff --git a/nbri_ehr/resources/queries/study/birth.js b/nbri_ehr/resources/queries/study/birth.js index 2174306..9c160fd 100644 --- a/nbri_ehr/resources/queries/study/birth.js +++ b/nbri_ehr/resources/queries/study/birth.js @@ -22,6 +22,11 @@ function isBlankGeneration(value) { return value === null || value === undefined || value === ''; } +// UNKNOWN is a placeholder parent, so it must not supply the newborn's species, origin or generation +function knownParent(value) { + return value && String(value).toUpperCase() !== 'UNKNOWN' ? value : null; +} + // opens one assignment record against the animal being entered; each dataset carries the assignment under its own field function createAssignment(scriptErrors, dataset, fieldName, value, row) { if (!value) @@ -177,8 +182,8 @@ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Even Id: row.Id, date: row.date, calculated_status: calc_status, - dam: row['Id/demographics/dam'] || null, - sire: row['Id/demographics/sire'] || null, + dam: knownParent(row['Id/demographics/dam']), + sire: knownParent(row['Id/demographics/sire']), species: row['Id/demographics/species'] || null, birth: row.date || null, gender: row['Id/demographics/gender'] || null, diff --git a/nbri_ehr/resources/queries/study/demographics.js b/nbri_ehr/resources/queries/study/demographics.js index ea36be3..91ae9bb 100644 --- a/nbri_ehr/resources/queries/study/demographics.js +++ b/nbri_ehr/resources/queries/study/demographics.js @@ -54,4 +54,12 @@ function onUpsert(helper, scriptErrors, row, oldRow){ } } } + + // UNKNOWN is a placeholder parent; stored, every parent-based query would treat the animals recorded against it as siblings + if (row.dam && String(row.dam).toUpperCase() === 'UNKNOWN') { + row.dam = null; + } + if (row.sire && String(row.sire).toUpperCase() === 'UNKNOWN') { + row.sire = null; + } } diff --git a/nbri_ehr/resources/queries/study/demographicsFamily.sql b/nbri_ehr/resources/queries/study/demographicsFamily.sql new file mode 100644 index 0000000..77dd8fd --- /dev/null +++ b/nbri_ehr/resources/queries/study/demographicsFamily.sql @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +-- parents rather than the raw columns, which drops the UNKNOWN placeholder parent +SELECT + +d1.id, + +d1.Id.parents.dam AS dam, + +d1.Id.parents.sire AS sire, + +dam.Id.parents.dam AS MaternalGranddam, + +dam.Id.parents.sire AS MaternalGrandsire, + +sire.Id.parents.dam AS PaternalGranddam, + +sire.Id.parents.sire AS PaternalGrandsire, + +d1.qcstate + +FROM study.Demographics d1 + +LEFT JOIN study.Demographics dam + ON (d1.Id.parents.dam = dam.id) + +LEFT JOIN study.Demographics sire + ON (d1.Id.parents.sire = sire.id) diff --git a/nbri_ehr/resources/queries/study/demographicsOffspring.sql b/nbri_ehr/resources/queries/study/demographicsOffspring.sql index 9feda19..081992a 100644 --- a/nbri_ehr/resources/queries/study/demographicsOffspring.sql +++ b/nbri_ehr/resources/queries/study/demographicsOffspring.sql @@ -8,14 +8,15 @@ SELECT d.id as Id, d2.id AS Offspring, d2.birth AS date, -d2.sire, -d2.dam, +d2.id.parents.sire AS sire, +d2.id.parents.dam AS dam, d2.gender AS sex, d.qcstate FROM study.Demographics d + -- parents rather than the raw columns, which drops the UNKNOWN placeholder parent INNER JOIN study.Demographics d2 -ON ((d2.sire = d.id OR d2.dam = d.id) AND d.id != d2.id) +ON ((d2.id.parents.sire = d.id OR d2.id.parents.dam = d.id) AND d.id != d2.id) -group by d.id, d2.id, d2.birth, d2.sire, d2.dam, d2.gender, d.qcstate +group by d.id, d2.id, d2.birth, d2.id.parents.sire, d2.id.parents.dam, d2.gender, d.qcstate diff --git a/nbri_ehr/resources/queries/study/demographicsParents.sql b/nbri_ehr/resources/queries/study/demographicsParents.sql index 91b6d5c..8a84029 100644 --- a/nbri_ehr/resources/queries/study/demographicsParents.sql +++ b/nbri_ehr/resources/queries/study/demographicsParents.sql @@ -14,17 +14,24 @@ * limitations under the License. */ SELECT - d.id, - d.dam as dam, + p.id, + p.dam, 'Observed' as damType, - d.sire as sire, + p.sire, 'Observed' as sireType, CASE - WHEN d.dam IS NOT NULL AND d.sire IS NOT NULL THEN 2 - WHEN d.dam IS NOT NULL OR d.sire IS NOT NULL THEN 1 + WHEN p.dam IS NOT NULL AND p.sire IS NOT NULL THEN 2 + WHEN p.dam IS NOT NULL OR p.sire IS NOT NULL THEN 1 ELSE 0 END as numParents -FROM study.demographics d +FROM ( + -- UNKNOWN is a placeholder parent; left in, every query joining on Id/parents would treat its offspring as siblings + SELECT + d.id, + CASE WHEN UPPER(d.dam) = 'UNKNOWN' THEN NULL ELSE d.dam END as dam, + CASE WHEN UPPER(d.sire) = 'UNKNOWN' THEN NULL ELSE d.sire END as sire + FROM study.demographics d +) p -- TODO: Incorporate fostering? Genetic testing? diff --git a/nbri_ehr/resources/queries/study/parentageSummary.sql b/nbri_ehr/resources/queries/study/parentageSummary.sql index 733a6ab..f507d3e 100644 --- a/nbri_ehr/resources/queries/study/parentageSummary.sql +++ b/nbri_ehr/resources/queries/study/parentageSummary.sql @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +-- parents rather than the raw columns, which drops the UNKNOWN placeholder parent SELECT d.Id, d.date, - d.dam as parent, + d.Id.parents.dam as parent, 'Dam' as relationship, 'Observed' as method @@ -28,7 +29,7 @@ UNION ALL SELECT d.Id, d.date, - d.sire as parent, + d.Id.parents.sire as parent, 'Sire' as relationship, 'Observed' as method diff --git a/nbri_ehr/resources/web/nbri_ehr/panel/SnapshotPanel.js b/nbri_ehr/resources/web/nbri_ehr/panel/SnapshotPanel.js index 1161973..1f0895b 100644 --- a/nbri_ehr/resources/web/nbri_ehr/panel/SnapshotPanel.js +++ b/nbri_ehr/resources/web/nbri_ehr/panel/SnapshotPanel.js @@ -394,10 +394,16 @@ Ext4.define('NBRI_EHR.panel.SnapshotPanel', { appendDataResults: function(toSet, results, id){ this.callParent(arguments); - this.appendPregnancy(toSet, results); + this.appendPregnancy(toSet, results, id); }, - appendPregnancy: function(toSet, results){ + appendPregnancy: function(toSet, results, id){ + // UNKNOWN is a placeholder ID, so the conceptions recorded against it describe no single animal + if (id && id.toUpperCase() === 'UNKNOWN'){ + toSet['pregnant'] = ''; + return; + } + var records = results ? results.getData()['activeConceptions'] : null; // getEHRContext returns null when the study container property is unset; fall back to the current container var ctx = EHR.Utils.getEHRContext() || {}; diff --git a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java index 12907ca..504044e 100644 --- a/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java +++ b/nbri_ehr/src/org/labkey/nbri_ehr/dataentry/section/NBRIBirthFormSection.java @@ -53,6 +53,8 @@ public NBRIBirthFormSection() super("study", "birth", "Births", false); addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/window/StartWithConceptionWindow.js")); addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/field/ConceptionField.js")); + addClientDependency(ClientDependency.supplierFromPath("ehr/window/FormBulkAddWindow.js")); + addClientDependency(ClientDependency.supplierFromPath("nbri_ehr/window/FormBulkAddWindow.js")); } @Override @@ -98,6 +100,7 @@ public List getTbarMoreActionButtons() { List defaultButtons = super.getTbarMoreActionButtons(); defaultButtons.remove("GUESSPROJECT"); + defaultButtons.add("NBRI_FORM_BULK_ADD"); return defaultButtons; } } \ No newline at end of file