diff --git a/onprc_ehr/resources/queries/study/ParentageMismatchGeneticandObservedDams.sql b/onprc_ehr/resources/queries/study/ParentageMismatchGeneticandObservedDams.sql
new file mode 100644
index 000000000..33532cdd0
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/ParentageMismatchGeneticandObservedDams.sql
@@ -0,0 +1,53 @@
+/*
+ Added by Kolli, Feb 2026
+ Refer tkt# 14114
+ Get data where genetic and observed dam do not match, AND foster dam ISBLANK AND Observed Dam IS NOT BLANK
+*/
+
+SELECT
+ d.Id,
+ d.Id.curLocation.area AS Area,
+ coalesce(p2.parent, '') as geneticDam,
+ coalesce(b.dam, '') as observedDam
+
+FROM study.demographics d
+
+LEFT JOIN (
+ SELECT
+ p2.Id,
+ MAX(p2.parent) AS parent
+ FROM study.parentage p2
+ WHERE (p2.method = 'Genetic' OR p2.method = 'Provisional Genetic')
+ AND p2.relationship = 'Dam'
+ AND p2.enddate IS NULL
+ GROUP BY p2.Id
+) p2 ON d.Id = p2.Id
+
+LEFT JOIN (
+ SELECT
+ p3.Id,
+ MAX(p3.parent) AS parent
+ FROM study.parentage p3
+ WHERE p3.relationship = 'Foster Dam'
+ AND p3.enddate IS NULL
+ GROUP BY p3.Id
+) p3 ON d.Id = p3.Id
+
+LEFT JOIN study.birth b
+ ON b.Id = d.Id
+
+WHERE d.calculated_status.code IN ('Alive', 'Dead') AND d.qcstate = 18
+ /* exclude foster-dam cases (NULL or blank only) */
+ AND COALESCE(RTRIM(LTRIM(CAST(p3.parent AS VARCHAR(50)))), '') = ''
+
+ /* exclude blank observed dam */
+ AND COALESCE(RTRIM(LTRIM(CAST(b.dam AS VARCHAR(50)))), '') <> ''
+
+ /* exclude blank genetic dam */
+ AND COALESCE(RTRIM(LTRIM(CAST(p2.parent AS VARCHAR(50)))), '') <> ''
+
+ /* mismatch observed vs genetic */
+ AND COALESCE(RTRIM(LTRIM(CAST(b.dam AS VARCHAR(50)))), '') <>
+ COALESCE(RTRIM(LTRIM(CAST(p2.parent AS VARCHAR(50)))), '')
+
+
diff --git a/onprc_ehr/resources/queries/study/ParentageMismatchGeneticsandObservedDams.query.xml b/onprc_ehr/resources/queries/study/ParentageMismatchGeneticsandObservedDams.query.xml
new file mode 100644
index 000000000..7a22c4f5c
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/ParentageMismatchGeneticsandObservedDams.query.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Mismatched Genetic and Observed Dams
+
+
+
+
\ No newline at end of file
diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java
index 8a5363df3..d9ee66e58 100644
--- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java
+++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java
@@ -312,6 +312,69 @@ protected void roomsReportingNegativeCagesAvailable(final Container c, User u, f
}
}
+ /**
+ * Kollil, Jan, 2026 :
+ * Alert title: WARNING: There are [x total] mismatches of observed and genetic dam data requiring review
+ * Format: Table
+ * 5 columns: animal ID, area, genetic dam, observed dam
+ * Alert criteria: genetic and observed dam do not match, AND foster dam ISBLANK.
+ * Refer Tkt# 10897 for more details
+ */
+ protected void mismatchedObservedAndGeneticDam(final Container c, User u, final StringBuilder msg)
+ {
+ if (QueryService.get().getUserSchema(u, c, "study") == null) {
+ msg.append("Warning: The study schema has not been enabled in this folder, so the alert cannot run!
");
+ return;
+ }
+ //Fasts query
+ TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("MismatchedObservedandGeneticDams", ContainerFilter.Type.AllFolders.create(c, u));
+ TableSelector ts = new TableSelector(ti, null, null);
+ long count = ts.getRowCount();
+
+ //Get num of rows
+ if (count > 0) {
+ msg.append(" WARNING: There are " + count + " mismatches of observed and genetic dam data requiring review");
+ msg.append("Click here to view the fast treatments in PRIME
\n");
+ msg.append("
");
+ }
+ else {
+ msg.append(" There are NO mismatches of observed and genetic dam data! ");
+ msg.append("
");
+ }
+
+ //Display the daily report in the email
+ if (count > 0)
+ {
+ Set columns = new HashSet<>();
+ columns.add(FieldKey.fromString("Id"));
+ columns.add(FieldKey.fromString("area"));
+ columns.add(FieldKey.fromString("geneticdam"));
+ columns.add(FieldKey.fromString("observeddam"));
+
+ final Map colMap = QueryService.get().getColumns(ti, columns);
+ TableSelector ts2 = new TableSelector(ti, colMap.values(), null, null);
+
+ msg.append("
\n");
+ msg.append("");
+ msg.append("");
+ msg.append("| Id | Area | Genetic Dam | Observed Dam |
");
+
+ ts2.forEach(object -> {
+ Results rs = new ResultsImpl(object, colMap);
+ String url = getParticipantURL(c, rs.getString("Id"));
+
+ msg.append("");
+ msg.append("| " + PageFlowUtil.filter(rs.getString("Id")) + " | \n");
+ msg.append("" + PageFlowUtil.filter(rs.getString("area")) + " | ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("geneticdam")) + " | ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("observeddam")) + " | ");
+ msg.append("
");
+ });
+ msg.append("
");
+ }
+ }
+ //End of mismatched Dam alert
+
/**
* Finds all rooms with animals of mixed viral status
* Modified by Kollil, 2/17/2023
diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java
index c7d35ab92..2aac477b5 100644
--- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java
+++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java
@@ -74,6 +74,10 @@ public String getMessageBodyHTML(Container c, User u)
doHousingChecks(c, u, msg);
transfersYesterday(c, u, msg);
roomsWithMixedViralStatus(c, u, msg);
+ /*Added by kollil, Jan, 2026
+ Refer to tkt # 14114
+ */
+ mismatchedObservedAndGeneticDam(c,u,msg);
livingAnimalsWithoutWeight(c, u, msg);
hospitalAnimalsWithoutCase(c, u, msg);