From 3d03ff644c74e5c6cbafef957843659c0517d2fb Mon Sep 17 00:00:00 2001 From: Bernard Siebens Date: Fri, 7 Aug 2026 22:12:42 +0200 Subject: [PATCH] Show a child's guardians' phone numbers on their Personal information card Member.guardians already scoped correctly to "the parents/guardians of the families where this member is the CHILD" -- no model changes needed. Adds clearly-labelled phone/emergency phone rows per guardian plus a dial button each, following the same tel: link pattern already used for the member's own numbers. Empty for members who aren't a child in any family. --- .../templates/management/member_detail.html | 29 +++++++++++++++++ management/tests.py | 31 +++++++++++++++++++ management/views.py | 4 +++ 3 files changed, 64 insertions(+) diff --git a/management/templates/management/member_detail.html b/management/templates/management/member_detail.html index 5f0dee0..436599e 100644 --- a/management/templates/management/member_detail.html +++ b/management/templates/management/member_detail.html @@ -28,6 +28,16 @@
{% trans "Emergency phone" %}
{{ member.emergency_phone.as_international|default:"-" }}
+ {% for guardian in guardians %} +
+
{% trans "Parent phone" %} — {{ guardian.get_full_name }}
+
{{ guardian.phone.as_international|default:"-" }}
+
+
+
{% trans "Parent emergency phone" %} — {{ guardian.get_full_name }}
+
{{ guardian.emergency_phone.as_international|default:"-" }}
+
+ {% endfor %}
@@ -38,6 +48,25 @@ {% lucide "shield-alert" size=14 %} {% trans "Emergency call" %} {% endif %}
+ + {% if guardians %} +
+
+ {% lucide "users" size=12 %} {% trans "Parent/guardian contact" %} +
+ {% for guardian in guardians %} + {% if guardian.phone or guardian.emergency_phone %} +
+ {% if guardian.phone %} + {% lucide "phone" size=14 %} {% blocktrans with name=guardian.get_full_name %}Call {{ name }}{% endblocktrans %} + {% endif %} + {% if guardian.emergency_phone %} + {% lucide "shield-alert" size=14 %} {% blocktrans with name=guardian.get_full_name %}Emergency: {{ name }}{% endblocktrans %} + {% endif %} +
+ {% endif %} + {% endfor %} + {% endif %} diff --git a/management/tests.py b/management/tests.py index 493cbc1..d61d7c1 100644 --- a/management/tests.py +++ b/management/tests.py @@ -1087,6 +1087,37 @@ class MemberFamilyAttachDetachTests(ManagementTestBase): self.assertNotIn(family, response.context["attach_to_family_form"].fields["family"].queryset) + def test_a_childs_page_shows_their_guardians_phone_numbers(self): + family = Family.objects.create() + parent = Member.objects.create(first_name="Pat", last_name="Parent", phone="+32470000001", emergency_phone="+32470000002") + FamilyMembership.objects.create(family=family, member=self.standalone, role=FamilyMembership.FamilyRole.CHILD) + FamilyMembership.objects.create(family=family, member=parent, role=FamilyMembership.FamilyRole.PARENT) + + response = self.club_get("member_detail", self.standalone.pk) + + self.assertIn(parent, response.context["guardians"]) + self.assertContains(response, "Pat Parent") + self.assertContains(response, "tel:+32 470 00 00 01") + self.assertContains(response, "tel:+32 470 00 00 02") + + def test_a_parents_page_does_not_show_guardian_numbers(self): + # self.standalone has no CHILD membership anywhere -- the section must not appear. + response = self.club_get("member_detail", self.standalone.pk) + + self.assertEqual(len(response.context["guardians"]), 0) + self.assertNotContains(response, "Parent/guardian contact") + + def test_a_guardian_with_no_phone_numbers_gets_no_dial_buttons(self): + family = Family.objects.create() + parent = Member.objects.create(first_name="Pat", last_name="Parent") + FamilyMembership.objects.create(family=family, member=self.standalone, role=FamilyMembership.FamilyRole.CHILD) + FamilyMembership.objects.create(family=family, member=parent, role=FamilyMembership.FamilyRole.PARENT) + + response = self.club_get("member_detail", self.standalone.pk) + + self.assertContains(response, "Pat Parent") + self.assertNotContains(response, "tel:") + class MemberDeleteTests(ManagementTestBase): def setUp(self): diff --git a/management/views.py b/management/views.py index 6da6707..4ad1e76 100644 --- a/management/views.py +++ b/management/views.py @@ -590,6 +590,10 @@ class MemberDetailView(ClubStaffRequiredMixin, DetailView): attach_to_family_form=AttachToFamilyForm(club=self.request.club, member=self.object), current_membership=ClubMembership.objects.filter(club=self.request.club, member=self.object, season=current_season(self.request.club)).first(), membership_history=ClubMembership.objects.filter(club=self.request.club, member=self.object).select_related("season").order_by("-season__start_date"), + # Non-empty only when `member` is a CHILD in some family -- that's the same + # signal the Personal information card uses to decide whether to show parent + # contact numbers at all. + guardians=self.object.guardians, **kwargs, )