Add a No-shows count to the player detail sheet

To answer the question this was built to address: "Absent" only ever reads
the RSVP (status=absent) -- someone who said they were coming but never
turned up still counts as present there, since present/absent don't touch
showed_up at all. member_attendance_counts now also returns no_shows, same
present/selected + showed_up=False definition team_no_shows already uses,
so that case shows up as its own number instead of being invisible.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 14:06:23 +02:00
parent 3501dbce94
commit 4af598500b
4 changed files with 56 additions and 1 deletions

View File

@@ -62,6 +62,10 @@
<div class="font-display text-2xl leading-none font-extrabold text-dim tabular-nums">{{ attendance_counts.no_reply }}</div>
<div class="mt-1 font-display text-[10px] font-extrabold tracking-wide text-muted uppercase">{% trans "No reply" %}</div>
</div>
<div class="flex-1">
<div class="font-display text-2xl leading-none font-extrabold text-warn-text tabular-nums">{{ attendance_counts.no_shows }}</div>
<div class="mt-1 font-display text-[10px] font-extrabold tracking-wide text-muted uppercase">{% trans "No-shows" %}</div>
</div>
</div>
</div>

View File

@@ -10,6 +10,7 @@ from icalendar import Calendar as ICalCalendar
from club.models import Club, ClubMembership, DuesInvoice, MemberRequirementStatus, OnboardingRequirement, Season, Sponsor
from events.models import Attendance, Event, EventReferee, Lineup, LineupSelection, Location, RefereeSignup
from events.services.attendance import record_check_in
from members.models import Family, FamilyMembership, Member
from news.models import News
from notifications.models import Notification
@@ -2766,6 +2767,18 @@ class CoachRosterMemberViewTests(TestCase):
self.assertEqual(response.context["attendance_counts"]["present"], 1)
def test_shows_no_shows(self):
past_event = Event.objects.create(club=self.club, title="Past practice", kind=Event.EventKind.TRAINING, start=timezone.now() - datetime.timedelta(days=2), season=self.season)
past_event.teams.add(self.team)
attendance, _created = Attendance.objects.update_or_create(event=past_event, member=self.player, defaults={"status": Attendance.AttendanceStatus.PRESENT})
record_check_in(attendance, showed_up=False)
self.client.force_login(self.user)
response = self._get()
self.assertEqual(response.context["attendance_counts"]["no_shows"], 1)
self.assertContains(response, "No-shows")
def test_managing_staff_sees_the_edit_form_and_remove_button(self):
self.client.force_login(self.user)