Notify a member once when a roster/group change adds them to new events
Joining a team or group already re-synced Attendance rows for its upcoming events (events/signals.py), but did so silently. A fresh membership (not a field edit, not a removal) now sends one summary notification -- "N new events on your calendar" -- rather than one per event, so joining mid-season with a whole recurring series already scheduled doesn't flood the member with pushes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from .attendance import (
|
||||
effective_members,
|
||||
notify_newly_invited,
|
||||
player_attendance_rankings,
|
||||
players_who_missed_recent_practices,
|
||||
record_check_in,
|
||||
@@ -24,6 +25,7 @@ __all__ = [
|
||||
"effective_members",
|
||||
"generate_occurrences",
|
||||
"horizon",
|
||||
"notify_newly_invited",
|
||||
"occurrence_datetimes",
|
||||
"player_attendance_rankings",
|
||||
"players_who_missed_recent_practices",
|
||||
|
||||
@@ -18,11 +18,14 @@ deliberate staff decision that should win regardless.
|
||||
|
||||
from django.db.models import Count, Q
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ngettext
|
||||
|
||||
from club.models import ClubMembership, Season
|
||||
from club.services.onboarding import blocked_member_ids_for_event
|
||||
from events.models import Attendance, Event
|
||||
from members.models import Member
|
||||
from notifications.services import notify_members
|
||||
from teams.models import TeamMembership
|
||||
|
||||
|
||||
@@ -85,6 +88,22 @@ def sync_event_attendances(event):
|
||||
event.attendances.filter(member_id__in=to_remove).delete()
|
||||
|
||||
|
||||
def notify_newly_invited(member, *, club, events):
|
||||
"""One notification (push+email), not one per event -- used when a
|
||||
roster/group change (events/signals.py's sync_on_roster_change/
|
||||
sync_on_group_membership_change) adds ``member`` to a team/group that
|
||||
already has upcoming events on the calendar. A flood of one-per-event
|
||||
pushes for, say, joining a team mid-season with a whole recurring
|
||||
practice series already scheduled would be worse than useless -- same
|
||||
reasoning as news.tasks._dedupe_by_recipients's single-summary
|
||||
preference over a flood, just per-recipient instead of cross-family."""
|
||||
if not events:
|
||||
return
|
||||
title = _("New events on your calendar")
|
||||
body = ngettext("%(count)d new event has been added to your calendar.", "%(count)d new events have been added to your calendar.", len(events)) % {"count": len(events)}
|
||||
notify_members([member], club=club, title=title, body=body)
|
||||
|
||||
|
||||
def record_check_in(attendance, *, showed_up):
|
||||
"""Record whether ``attendance``'s member actually showed up, separate from
|
||||
their RSVP status -- the hook a future check-in UI (the coaches app) writes
|
||||
|
||||
Reference in New Issue
Block a user