Coverage for app/controllers/admin/volunteers.py: 26%
152 statements
« prev ^ index » next coverage.py v7.2.7, created at 2025-05-02 15:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2025-05-02 15:35 +0000
1from flask import request, render_template, redirect, url_for, flash, abort, g, json, jsonify, session
2from peewee import DoesNotExist, JOIN
3from datetime import datetime
4from playhouse.shortcuts import model_to_dict
5from app.controllers.admin import admin_bp
6from app.models.event import Event
7from app.models.program import Program
8from app.models.user import User
9from app.models.eventParticipant import EventParticipant
10from app.models.emergencyContact import EmergencyContact
11from app.logic.searchUsers import searchUsers
12from app.logic.volunteers import updateEventParticipants, getEventLengthInHours, addUserBackgroundCheck, setProgramManager, deleteUserBackgroundCheck
13from app.logic.participants import trainedParticipants, addPersonToEvent, getParticipationStatusForTrainings, sortParticipantsByStatus
14from app.logic.events import getPreviousSeriesEventData, getEventRsvpCount
15from app.models.eventRsvp import EventRsvp
16from app.models.backgroundCheck import BackgroundCheck
17from app.logic.createLogs import createActivityLog, createRsvpLog
18from app.logic.users import getBannedUsers, isBannedFromEvent
21@admin_bp.route('/searchVolunteers/<query>', methods = ['GET'])
22def getVolunteers(query):
23 '''Accepts user input and queries the database returning results that matches user search'''
25 return json.dumps(searchUsers(query))
27@admin_bp.route('/event/<eventID>/manage_volunteers', methods=['GET', 'POST'])
28def manageVolunteersPage(eventID):
29 """
30 Controller that handles POST and GET requests regarding the Manage Volunteers page.
32 POST: updates the event participants for a particular event by calling
33 updateEventParticipants on the form.
35 GET: retrieves all necessary participant lists and dictionaries and categorizes
36 the participants/volunteers into their respective participation statuses. Then
37 renders the manageVolunteers.html template.
38 """
39 try:
40 event = Event.get_by_id(eventID)
41 except DoesNotExist as e:
42 print(f"No event found for {eventID}", e)
43 abort(404)
45 # ------------ POST request ------------
46 if request.method == "POST":
47 volunteerUpdated = updateEventParticipants(request.form)
49 # error handling depending on the boolean returned from updateEventParticipants
50 if volunteerUpdated:
51 flash("Volunteer table succesfully updated", "success")
52 else:
53 flash("Error adding volunteer", "danger")
54 return redirect(url_for("admin.manageVolunteersPage", eventID=eventID))
56 # ------------ GET request ------------
57 elif request.method == "GET":
58 if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event))):
59 abort(403)
61 # ------- Grab the different lists of participants -------
62 trainedParticipantsForProgramAndTerm = trainedParticipants(event.program, event.term)
64 bannedUsersForProgram = [bannedUser.user for bannedUser in getBannedUsers(event.program)]
66 eventNonAttendedData, eventWaitlistData, eventVolunteerData, eventParticipants = sortParticipantsByStatus(event)
68 allRelevantUsers = list(set(participant.user for participant in (eventParticipants + eventNonAttendedData + eventWaitlistData + eventVolunteerData)))
69 # ----------- Get miscellaneous data -----------
71 participationStatusForTrainings = getParticipationStatusForTrainings(event.program, allRelevantUsers, event.term)
73 eventLengthInHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate)
75 repeatingVolunteers = getPreviousSeriesEventData(event.seriesId)
77 currentRsvpAmount = getEventRsvpCount(event.id)
79 # ----------- Render template with all of the data ------------
80 return render_template("/events/manageVolunteers.html",
81 eventVolunteerData = eventVolunteerData,
82 eventNonAttendedData = eventNonAttendedData,
83 eventWaitlistData = eventWaitlistData,
84 eventLength = eventLengthInHours,
85 event = event,
86 repeatingVolunteers = repeatingVolunteers,
87 bannedUsersForProgram = bannedUsersForProgram,
88 trainedParticipantsForProgramAndTerm = trainedParticipantsForProgramAndTerm,
89 participationStatusForTrainings = participationStatusForTrainings,
90 currentRsvpAmount = currentRsvpAmount)
92@admin_bp.route('/event/<eventID>/volunteer_details', methods=['GET'])
93def volunteerDetailsPage(eventID):
94 try:
95 event = Event.get_by_id(eventID)
96 except DoesNotExist as e:
97 print(f"No event found for {eventID}", e)
98 abort(404)
100 if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event))):
101 abort(403)
103 eventRsvpData = list(EventRsvp.select(EmergencyContact, EventRsvp)
104 .join(EmergencyContact, JOIN.LEFT_OUTER, on=(EmergencyContact.user==EventRsvp.user))
105 .where(EventRsvp.event==event))
106 eventParticipantData = list(EventParticipant.select(EmergencyContact, EventParticipant)
107 .join(EmergencyContact, JOIN.LEFT_OUTER, on=(EmergencyContact.user==EventParticipant.user))
108 .where(EventParticipant.event==event))
110 waitlistUser = list(set([obj for obj in eventRsvpData if obj.rsvpWaitlist]))
111 rsvpUser = list(set([obj for obj in eventRsvpData if not obj.rsvpWaitlist ]))
113 return render_template("/events/volunteerDetails.html",
114 waitlistUser = waitlistUser,
115 attendedUser= eventParticipantData,
116 rsvpUser= rsvpUser,
117 event = event)
120@admin_bp.route('/addVolunteersToEvent/<eventId>', methods = ['POST'])
121def addVolunteer(eventId):
122 event = Event.get_by_id(eventId)
123 successfullyAddedVolunteer = False
124 usernameList = request.form.getlist("selectedVolunteers[]")
125 successfullyAddedVolunteer = False
126 alreadyAddedList = []
127 addedSuccessfullyList = []
128 errorList = []
130 for user in usernameList:
131 userObj = User.get_by_id(user)
132 successfullyAddedVolunteer = addPersonToEvent(userObj, event)
133 if successfullyAddedVolunteer == "already in":
134 alreadyAddedList.append(userObj.fullName)
135 else:
136 if successfullyAddedVolunteer:
137 addedSuccessfullyList.append(userObj.fullName)
138 else:
139 errorList.append(userObj.fullName)
141 volunteers = ""
142 if alreadyAddedList:
143 volunteers = ", ".join(vol for vol in alreadyAddedList)
144 flash(f"{volunteers} was already added to this event.", "warning")
146 if addedSuccessfullyList:
147 volunteers = ", ".join(vol for vol in addedSuccessfullyList)
148 flash(f"{volunteers} added successfully.", "success")
150 if errorList:
151 volunteers = ", ".join(vol for vol in errorList)
152 flash(f"Error when adding {volunteers} to event.", "danger")
154 if 'ajax' in request.form and request.form['ajax']:
155 return ''
157 return redirect(url_for('admin.manageVolunteersPage', eventID = eventId))
159@admin_bp.route('/rsvpFromWaitlist/<username>/<eventId>', methods = ['POST'])
160def rsvpFromWaitlist(username, eventId):
161 event = Event.get_by_id(eventId)
162 isProgramManager = g.current_user.isProgramManagerFor(event.program)
163 if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager):
164 waitlistUsers = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == username, EventRsvp.event==eventId).execute()
165 if (waitlistUsers):
166 createRsvpLog(event.id, f"Moved {waitlistUsers[0].user.fullName} from waitlist to RSVP.")
167 (EventRsvp.update(rsvpWaitlist = False).where(EventRsvp.event_id == eventId, EventRsvp.user_id == username)).execute()
168 return ""
170@admin_bp.route('/addVolunteersToEvent/<username>/<eventId>/isBanned', methods = ['GET'])
171def isVolunteerBanned(username, eventId):
172 return {"banned":1} if isBannedFromEvent(username, eventId) else {"banned":0}
174@admin_bp.route('/removeVolunteerFromEvent', methods = ['POST'])
175def removeVolunteerFromEvent():
176 user = request.form.get('username')
177 eventID = request.form.get('eventId')
178 if g.current_user.isAdmin:
179 userInRsvpTable = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == user, EventRsvp.event==eventID).execute()
180 if (userInRsvpTable):
181 rsvpUser = userInRsvpTable[0]
182 if rsvpUser.rsvpWaitlist:
183 createRsvpLog(eventID, f"Removed {rsvpUser.user.fullName} from waitlist.")
184 else:
185 createRsvpLog(eventID, f"Removed {rsvpUser.user.fullName} from RSVP list.")
186 (EventParticipant.delete().where(EventParticipant.user==user, EventParticipant.event==eventID)).execute()
187 (EventRsvp.delete().where(EventRsvp.user==user, EventRsvp.event==eventID)).execute()
188 flash("Volunteer successfully removed", "success")
189 return ""
191@admin_bp.route('/addBackgroundCheck', methods = ['POST'])
192def addBackgroundCheck():
193 if g.current_user.isCeltsAdmin:
194 eventData = request.form
195 user = eventData['user']
196 bgStatus = eventData['bgStatus']
197 type = eventData['bgType']
198 dateCompleted = eventData['bgDate']
199 addUserBackgroundCheck(user, type, bgStatus, dateCompleted)
200 return ""
202@admin_bp.route('/deleteBackgroundCheck', methods = ['POST'])
203def deleteBackgroundCheck():
204 if g.current_user.isCeltsAdmin:
205 backgroundData = request.form
206 bgToDelete = BackgroundCheck.get_by_id(backgroundData['bgID'])
207 session["lastDeletedBgCheck"] = bgToDelete.id
208 user = g.current_user
209 deleteUserBackgroundCheck(bgToDelete.id, user)
210 return ""
212@admin_bp.route('/updateProgramManager', methods=["POST"])
213def updateProgramManager():
214 if g.current_user.isCeltsAdmin:
215 data =request.form
216 username = User.get(User.username == data["username"])
217 program = Program.get_by_id(data['programId'])
218 setProgramManager(data["username"], data["programId"], data["action"])
219 createActivityLog(f'{username.firstName} has been {data["action"]}ed as a Program Manager for {program.programName}')
220 return ""
221 else:
222 abort(403)
224@admin_bp.route("/updatePhone", methods=["POST"])
225def updatePhone():
226 newinfo=request.form
227 User.update(phoneNumber=newinfo["phoneNumber"]).where(User.username==newinfo["username"]).execute()
228 return ""