feat(import): merge animals with different DOBs if their parent names match
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m2s
CI / Frontend Tests (Node/Vite) (push) Successful in 9m35s
CI / Docker Build & Push (push) Failing after 12s

This commit is contained in:
2026-06-21 22:23:59 +02:00
parent d2993418b6
commit 41ff973f9a
3 changed files with 111 additions and 15 deletions

View File

@@ -1173,6 +1173,17 @@ def main():
norm_b, keep_b = get_normalized_contact_name(raw_breeder)
raw_breeder = norm_b if keep_b else None
parent_refs = []
if old_litter_id:
rl = next((l for l in raw_litters if l.get("_scoped_id") == old_litter_id), None)
if rl:
f_name = rl.get("FatherName") or rl.get("fatherName") or rl.get("ParentMaleName") or rl.get("parentMaleName") or rl.get("_father_name")
m_name = rl.get("MotherName") or rl.get("motherName") or rl.get("ParentFemaleName") or rl.get("parentFemaleName") or rl.get("_mother_name")
if f_name:
parent_refs.append({"name": f_name, "roleGuess": "father"})
if m_name:
parent_refs.append({"name": m_name, "roleGuess": "mother"})
all_processed_gerbils.append({
"Id": new_guid,
"Name": name_val,
@@ -1198,6 +1209,7 @@ def main():
"CharacterNote": char_note,
"IsDeaf": is_deaf,
"IsResident": is_resident,
"parentRefs": parent_refs,
"_photos": rg.get("photos", []),
"_old_scoped_litter_id": old_litter_id,
"_eff_dob": eff_dob_val,
@@ -1306,6 +1318,7 @@ def main():
"CharacterNote": None,
"IsDeaf": is_deaf,
"IsResident": a_id in stammbaum_resident_ids,
"parentRefs": a.get("parentRefs", []),
"_photos": a.get("photos", []),
"_old_scoped_litter_id": scoped_litter_id,
"_eff_dob": dob_val or "2010-01-01",
@@ -1364,6 +1377,15 @@ def main():
# Residents: if sold/given away, it's not a resident
is_resident = not bool(o_name)
parent_refs = []
if scoped_litter_id:
dl = next((l for l in docx_litters if docx_litter_id_map.get((l["wsCode"], parse_date(l["dob"]))) == scoped_litter_id), None)
if dl:
if dl.get("fatherName"):
parent_refs.append({"name": dl["fatherName"], "roleGuess": "father"})
if dl.get("motherName"):
parent_refs.append({"name": dl["motherName"], "roleGuess": "mother"})
all_processed_gerbils.append({
"Id": scoped_id,
"Name": name_val,
@@ -1389,6 +1411,7 @@ def main():
"CharacterNote": None,
"IsDeaf": None,
"IsResident": is_resident,
"parentRefs": parent_refs,
"_photos": da.get("photos", []),
"_old_scoped_litter_id": scoped_litter_id,
"_eff_dob": dob_val or "2020-01-01",
@@ -1418,13 +1441,27 @@ def main():
bd1 = g1.get("_birth_date")
bd2 = g2.get("_birth_date")
# If both have explicit birth dates, they must match within 30 days
if bd1 and bd2:
days1 = date_to_days(bd1)
days2 = date_to_days(bd2)
if days1 is not None and days2 is not None:
if abs(days1 - days2) > 30:
return False
# New rule: if name and parents match, they are compatible regardless of DOB!
p1 = g1.get("parentRefs", [])
p2 = g2.get("parentRefs", [])
f1 = next((p["name"] for p in p1 if p.get("roleGuess") == "father"), "")
m1 = next((p["name"] for p in p1 if p.get("roleGuess") == "mother"), "")
f2 = next((p["name"] for p in p2 if p.get("roleGuess") == "father"), "")
m2 = next((p["name"] for p in p2 if p.get("roleGuess") == "mother"), "")
parents_match = False
if f1 and f2 and m1 and m2:
if normalize_name(f1) == normalize_name(f2) and normalize_name(m1) == normalize_name(m2):
parents_match = True
if not parents_match:
# If both have explicit birth dates, they must match within 30 days
if bd1 and bd2:
days1 = date_to_days(bd1)
days2 = date_to_days(bd2)
if days1 is not None and days2 is not None:
if abs(days1 - days2) > 30:
return False
# If g1 has birth date, and g2 has parenting dates, birth date must be before parenting dates
p_dates2 = parent_litter_dates.get(g2["Id"], [])