Skip to content
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
fe07fd0
Updated RSVP before and After Status
Meatchema Feb 23, 2026
1a5fecc
re-implemented the attended status for the non-rsvp events
Meatchema Feb 23, 2026
1fcf75e
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Mar 6, 2026
5c0226b
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Mar 9, 2026
129b188
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Mar 12, 2026
da9b9f5
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Mar 24, 2026
1137e06
Added Invited status into checkedbox javascript to allow for filtered…
Meatchema Mar 24, 2026
3ce5b3b
Merge branch 'development' of https://github.com/BCStudentSoftwareDev…
JohnCox2211 Mar 25, 2026
ea0d701
Add @propriety for RSVP and changed conditional to allow invited stat…
Meatchema Mar 30, 2026
03dfcf0
Added Conditional to allow accordion title of RSVP and Waitlist to ch…
Meatchema Mar 31, 2026
90aefc6
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Apr 2, 2026
7d89e1d
updated allLogs section to include invited user to create logs for bo…
Meatchema Apr 2, 2026
5ad6ee5
refined the way that the event message is passed rather than having t…
Meatchema Apr 2, 2026
afe5827
Updated Verbage of logs back to original verbage
Meatchema Apr 6, 2026
e4438dd
Changed ordering of table conditionals to prioritize the identificati…
Meatchema Apr 7, 2026
cc523f8
Added Marked message
Meatchema Apr 9, 2026
7a026e4
fixed format
Meatchema Apr 9, 2026
7b48463
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Apr 13, 2026
519291f
Added ability to created attended Logs after check boxing attended
Meatchema Apr 13, 2026
b3b88a2
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Apr 15, 2026
f38aaaf
Merge branch 'development' of https://github.com/BCStudentSoftwareDev…
Meatchema Apr 15, 2026
51043d0
Merge branch 'issue-1663-change-rsvp-language' of https://github.com/…
Meatchema Apr 15, 2026
01aff6c
removed old version of html status selector
Meatchema Apr 15, 2026
462c27e
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Apr 22, 2026
73d22ff
implemented a test for getTargetList condition function
Meatchema Apr 24, 2026
3b6e59c
Merge branch 'development' into issue-1663-change-rsvp-language
Meatchema Apr 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/controllers/admin/volunteers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
75 changes: 52 additions & 23 deletions app/logic/participants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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"
Expand Down Expand Up @@ -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
4 changes: 4 additions & 0 deletions app/models/eventRsvp.py
Original file line number Diff line number Diff line change
Expand Up @@ -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), )
1 change: 1 addition & 0 deletions app/static/js/volunteerDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand Down
8 changes: 6 additions & 2 deletions app/templates/events/manageVolunteers.html
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,11 @@ <h2 class="accordion-header">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed fs-4" type="button" data-bs-toggle="collapse" data-bs-target="#non-attended-collapse">
RSVP and Waitlist
{% if event.isRsvpRequired %}
RSVP and Waitlist
{% else %}
Invited and Waitlist
{% endif %}
</button>
</h2>
<div class="accordion-collapse collapse" id="non-attended-collapse">
Expand Down Expand Up @@ -275,7 +279,7 @@ <h2 class="accordion-header">
</td>
<td>{{participant.user.email}}</td>
<td>{{participant.user.phoneNumber}}</td>
<td>{{ 'Waitlist' if participant.rsvpWaitlist else 'RSVP' }}</td>
<td>{{ 'Waitlist' if participant.rsvpWaitlist else ('RSVP' if event.isRsvpRequired else 'Invited') }}</td>
<td>
<input
class="form-control number-only form-control input-sm"
Expand Down
46 changes: 24 additions & 22 deletions app/templates/events/volunteerDetails.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,31 +59,30 @@ <h4 class="nameSelect" nowrap><b>{{ 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') %}
<input class="displayCheckbox noprint" type="checkbox" name="selected_items" id="{{checkboxName}}Select" checked>
<label for="{{checkboxName}}Select">{{labelText}}</label><br>
{% endmacro %}
Expand All @@ -105,7 +104,7 @@ <h3 style="text-align: center; width:180%;">
<div class="row">
<div class="col">
<label><b>Volunteer Groups:</b></label><br>
{% if rsvpUser %}
{% if rsvpUser and event.isRsvpRequired %}
{{createCheckbox('rsvp')}}
{% endif %}
{% if waitlistUser %}
Expand All @@ -114,6 +113,9 @@ <h3 style="text-align: center; width:180%;">
{% if attendedUser %}
{{createCheckbox('attended')}}
{% endif %}
{% if rsvpUser and not event.isRsvpRequired %}
{{createCheckbox('invited')}}
{% endif %}
</div>
<div class="col">
<label><b>Included Information:</b></label><br>
Expand Down
Loading