diff --git a/app/controllers/admin/volunteers.py b/app/controllers/admin/volunteers.py index 2dbe81479..cf730ea73 100644 --- a/app/controllers/admin/volunteers.py +++ b/app/controllers/admin/volunteers.py @@ -115,11 +115,12 @@ def volunteerDetailsPage(eventID): waitlistUser = list(set([obj for obj in eventRsvpData if obj.rsvpWaitlist])) rsvpUser = list(set([obj for obj in eventRsvpData if not obj.rsvpWaitlist ])) - + attendedUser = list(set([obj for obj in eventParticipantData if not obj.rsvpWaitlist])) + return render_template("/events/volunteerDetails.html", waitlistUser = waitlistUser, - attendedUser= eventParticipantData, - rsvpUser= rsvpUser, + attendedUser = attendedUser, + rsvpUser = rsvpUser, event = event) diff --git a/app/logic/participants.py b/app/logic/participants.py index 630ea0aea..f896259aa 100644 --- a/app/logic/participants.py +++ b/app/logic/participants.py @@ -53,13 +53,30 @@ def addBnumberAsParticipant(bnumber, eventId): userStatus = "already signed in" else: + # Non-RSVP and RSVP event handling userStatus = "success" - # We are not using addPersonToEvent to do this because - # that function checks if the event is in the past, but - # someone could start signing people up via the kiosk - # before an event has started - totalHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) - EventParticipant.create (user=kioskUser, event=event, hoursEarned=totalHours) + if event.isRsvpRequired: + # RSVP event: standard logic (RSVP before event, attend after) + if event.isPastStart: + totalHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) + EventParticipant.create(user=kioskUser, event=event, hoursEarned=totalHours) + else: + if not checkUserRsvp(kioskUser, event): + currentRsvp = getEventRsvpCountsForTerm(event.term) + waitlist = currentRsvp[event.id] >= event.rsvpLimit if event.rsvpLimit is not None else False + EventRsvp.create(user=kioskUser, event=event, rsvpWaitlist=waitlist) + targetList = "the waitlist" if waitlist else "the RSVP list" + try: + if g.current_user.username == kioskUser.username: + createRsvpLog(event.id, f"{kioskUser.fullName} joined {targetList}.") + else: + createRsvpLog(event.id, f"Added {kioskUser.fullName} to {targetList}.") + except Exception: + pass + else: + # Non-RSVP event: scanner entry ALWAYS marks as attended regardless of timing + totalHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) + EventParticipant.create(user=kioskUser, event=event, hoursEarned=totalHours) return kioskUser, userStatus @@ -80,22 +97,34 @@ def addPersonToEvent(user, event): try: volunteerExists = checkUserVolunteer(user, event) rsvpExists = checkUserRsvp(user, event) - if event.isPastStart: - if not volunteerExists: - # We duplicate these two lines in addBnumberAsParticipant - eventHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) - EventParticipant.create(user = user, event = event, hoursEarned = eventHours) + + if event.isRsvpRequired: + # RSVP event logic + if event.isPastStart: + if not volunteerExists: + eventHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) + EventParticipant.create(user = user, event = event, hoursEarned = eventHours) + else: + if not rsvpExists: + currentRsvp = getEventRsvpCountsForTerm(event.term) + waitlist = currentRsvp[event.id] >= event.rsvpLimit if event.rsvpLimit is not None else 0 + EventRsvp.create(user = user, event = event, rsvpWaitlist = waitlist) + targetList = "the waitlist" if waitlist else "the RSVP list" + if g.current_user.username == user.username: + createRsvpLog(event.id, f"{user.fullName} joined {targetList}.") + else: + createRsvpLog(event.id, f"Added {user.fullName} to {targetList}.") else: - if not rsvpExists: - currentRsvp = getEventRsvpCountsForTerm(event.term) - waitlist = currentRsvp[event.id] >= event.rsvpLimit if event.rsvpLimit is not None else 0 - EventRsvp.create(user = user, event = event, rsvpWaitlist = waitlist) - - targetList = "the waitlist" if waitlist else "the RSVP list" - if g.current_user.username == user.username: - createRsvpLog(event.id, f"{user.fullName} joined {targetList}.") - else: - createRsvpLog(event.id, f"Added {user.fullName} to {targetList}.") + # Non-RSVP event logic + if event.isPastStart: + # After event: create EventParticipant (attended) + if not volunteerExists: + eventHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) + EventParticipant.create(user = user, event = event, hoursEarned = eventHours) + else: + # Before event: create EventRsvp (invited status) + if not rsvpExists: + EventRsvp.create(user = user, event = event, rsvpWaitlist = False) if volunteerExists or rsvpExists: return "already in" @@ -193,8 +222,8 @@ def sortParticipantsByStatus(event): # if rsvp is required for the event, grab all volunteers that are in the waitlist eventWaitlistData = [volunteer for volunteer in (eventParticipants + eventRsvpData) if volunteer.rsvpWaitlist and event.isRsvpRequired] - # put the rest of the users that are not on the waitlist into the volunteer data - eventVolunteerData = [volunteer for volunteer in eventNonAttendedData if volunteer not in eventWaitlistData] + # put all participants and non-waitlisted RSVPs into the volunteer data + eventVolunteerData = [volunteer for volunteer in (eventParticipants + eventNonAttendedData) if volunteer not in eventWaitlistData] eventNonAttendedData = [] return eventNonAttendedData, eventWaitlistData, eventVolunteerData, eventParticipants \ No newline at end of file diff --git a/app/models/eventRsvp.py b/app/models/eventRsvp.py index 8afdd47c2..d492a0e4c 100644 --- a/app/models/eventRsvp.py +++ b/app/models/eventRsvp.py @@ -9,6 +9,10 @@ class EventRsvp(baseModel): rsvpTime = DateTimeField(default=datetime.now) rsvpWaitlist = BooleanField(default=False) + @property + def rsvp(self): + # EventRsvp always represents an RSVP record, including invited participants. + return True class Meta: indexes = ( (('user', 'event'), True), ) diff --git a/app/static/js/volunteerDetails.js b/app/static/js/volunteerDetails.js index 1b6192a23..1b5aafdf7 100644 --- a/app/static/js/volunteerDetails.js +++ b/app/static/js/volunteerDetails.js @@ -28,6 +28,7 @@ $(document).ready(function () { const status = data[3].toLowerCase(); if (status === 'attended' && !$('#attendedSelect').is(':checked')) return false; if (status === 'rsvp' && !$('#rsvpSelect').is(':checked')) return false; + if (status === 'invited' && !$('#invitedSelect').is(':checked')) return false; if (status === 'waitlist' && !$('#waitlistSelect').is(':checked')) return false; return true; }); diff --git a/app/templates/events/manageVolunteers.html b/app/templates/events/manageVolunteers.html index aa66235fe..6b6c98aae 100644 --- a/app/templates/events/manageVolunteers.html +++ b/app/templates/events/manageVolunteers.html @@ -239,7 +239,11 @@

@@ -275,7 +279,7 @@

{{participant.user.email}} {{participant.user.phoneNumber}} - {{ 'Waitlist' if participant.rsvpWaitlist else 'RSVP' }} + {{ 'Waitlist' if participant.rsvpWaitlist else ('RSVP' if event.isRsvpRequired else 'Invited') }} {{ participant.user.firstName }} {{ participant {% macro printParticipants(type, attended, rsvp, waitlist) %} {% set seen = [] %} {% set combinedParticipants = attended + rsvp + waitlist %} - {% for p in combinedParticipants %} - {% set username = p.user.username %} - {% if username not in seen %} - {% set _ = seen.append(username) %} - {% set status = none %} - {% if p in attended %} - {% set status = 'attended'%} - {% elif p in rsvp %} - {% set status = 'rsvp'%} - {% elif p in waitlist %} - {% set status = 'waitlist'%} - {% endif %} - {% if status %} - {% if type == 'card' %} - {{ createCard(p, status) }} - {% elif type == 'table' %} - {{ createTable(p, status) }} - {% endif %} - {% endif %} - {% endif %} + {% for p in combinedParticipants | unique %} + {% if p in rsvp and not event.isRsvpRequired %} + {{createTable(p, 'invited') if type == 'table' else createCard(p, 'invited') }} + {% endif %} + {% if p in rsvp and event.isRsvpRequired %} + {{createTable(p, 'rsvp') if type == 'table' else createCard(p, 'rsvp') }} + {% endif %} + {% if p in attended%} + {{createTable(p, 'attended') if type == 'table' else createCard(p, 'attended') }} + {% endif %} + {% if p in waitlist %} + {{createTable(p, 'waitlisted') if type == 'table' else createCard(p, 'waitlisted') }} + {% endif %} {% endfor %} {% endmacro %} {% macro createCheckbox(checkboxName) %} - {% set labelText = "RSVP" if checkboxName == 'rsvp' else 'Waitlist' if checkboxName == 'waitlist' else 'Attended' %} + {%- set labelMap = { + 'rsvp': 'RSVP', + 'waitlist': 'Waitlisted', + 'attended': 'Attended', + 'invited': 'Invited' + } -%} + {% set labelText = labelMap.get(checkboxName, 'Invited') %}
{% endmacro %} @@ -105,7 +104,7 @@


- {% if rsvpUser %} + {% if rsvpUser and event.isRsvpRequired %} {{createCheckbox('rsvp')}} {% endif %} {% if waitlistUser %} @@ -114,6 +113,9 @@

{% if attendedUser %} {{createCheckbox('attended')}} {% endif %} + {% if rsvpUser and not event.isRsvpRequired %} + {{createCheckbox('invited')}} + {% endif %}