diff --git a/onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml b/onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml
new file mode 100644
index 000000000..5a237c10e
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Mismatched Genetic and Observed Dams
+
+
+
+
\ No newline at end of file
diff --git a/onprc_ehr/resources/queries/study/ParentageDamMismatch.sql b/onprc_ehr/resources/queries/study/ParentageDamMismatch.sql
new file mode 100644
index 000000000..f9e07f467
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/ParentageDamMismatch.sql
@@ -0,0 +1,61 @@
+/*
+ Added by Kolli, Feb 2026
+ Refer tkt# 14114 for details
+ Display 4 columns: Animal Id, Area, Genetic dam, Observed dam
+
+ Get genetic and observed dam mismatch data.
+ Use the following criteria,
+ * 1. One genetic dam per animal
+ * 2. Included Alive + Dead animals
+ * 3. Excludes animals that have a foster dam
+ * 4. Excludes rows where observedDam or geneticDam IS BLANK
+ * 5. Keeps only mismatches between observed and genetic dams
+ * 6. Excludes old parentage entries, enddate IS 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/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java
index 8a5363df3..3b62bd188 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,70 @@ protected void roomsReportingNegativeCagesAvailable(final Container c, User u, f
}
}
+ /**
+ * Kollil, Jan, 2026 :
+ * Refer tkt# 14114 for more details
+ * Alert title: WARNING: There are [x total] mismatches of observed and genetic dam data requiring review
+ * Format: Table
+ * 4 columns: Animal Id, Area, Genetic dam, Observed dam
+ * Alert criteria:
+ * 1. One genetic dam per animal
+ * 2. Included Alive + Dead animals
+ * 3. Excludes animals that have a foster dam
+ * 4. Excludes rows where observedDam or geneticDam IS BLANK
+ * 5. Keeps only mismatches between observed and genetic dams
+ * 6. Excludes old parentage entries, enddate IS BLANK
+ */
+ 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;
+ }
+
+ //Dam mismatch query
+ TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("ParentageDamMismatch", 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 them in a grid\n");
+
+ //Display the report in the email
+ 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("| " + 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("
");
+ });
+ }
+ else {
+ msg.append(" There are NO mismatches of observed and genetic dam data. ");
+ }
+ msg.append("
");
+ msg.append("
\n");
+ }
+ //End of Dam mismatch report
+
/**
* 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..1ca060cad 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);