Coverage for app/controllers/admin/volunteers.py: 26%
152 statements
« prev ^ index » next coverage.py v7.2.7, created at 2025-03-12 21:45 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2025-03-12 21:45 +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 = [participant.user for participant in (eventParticipants + eventNonAttendedData + eventWaitlistData)]
70 # ----------- Get miscellaneous data -----------
72 participationStatusForTrainings = getParticipationStatusForTrainings(event.program, allRelevantUsers, event.term)
74 eventLengthInHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate)
76 repeatingVolunteers = getPreviousSeriesEventData(event.seriesId)
78 currentRsvpAmount = getEventRsvpCount(event.id)
80 # ----------- Render template with all of the data ------------
81 return render_template("/events/manageVolunteers.html",
82 eventVolunteerData = eventVolunteerData,
83 eventNonAttendedData = eventNonAttendedData,
84 eventWaitlistData = eventWaitlistData,
85 eventLength = eventLengthInHours,
86 event = event,
87 repeatingVolunteers = repeatingVolunteers,
88 bannedUsersForProgram = bannedUsersForProgram,
89 trainedParticipantsForProgramAndTerm = trainedParticipantsForProgramAndTerm,
90 participationStatusForTrainings = participationStatusForTrainings,
91 currentRsvpAmount = currentRsvpAmount)
93@admin_bp.route('/event/<eventID>/volunteer_details', methods=['GET'])
94def volunteerDetailsPage(eventID):
95 try:
96 event = Event.get_by_id(eventID)
97 except DoesNotExist as e:
98 print(f"No event found for {eventID}", e)
99 abort(404)
101 if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event))):
102 abort(403)
104 eventRsvpData = list(EventRsvp.select(EmergencyContact, EventRsvp)
105 .join(EmergencyContact, JOIN.LEFT_OUTER, on=(EmergencyContact.user==EventRsvp.user))
106 .where(EventRsvp.event==event))
107 eventParticipantData = list(EventParticipant.select(EmergencyContact, EventParticipant)
108 .join(EmergencyContact, JOIN.LEFT_OUTER, on=(EmergencyContact.user==EventParticipant.user))
109 .where(EventParticipant.event==event))
111 waitlistUser = list(set([obj for obj in eventRsvpData if obj.rsvpWaitlist]))
112 rsvpUser = list(set([obj for obj in eventRsvpData if not obj.rsvpWaitlist ]))
114 return render_template("/events/volunteerDetails.html",
115 waitlistUser = waitlistUser,
116 attendedUser= eventParticipantData,
117 rsvpUser= rsvpUser,
118 event = event)
121@admin_bp.route('/addVolunteersToEvent/<eventId>', methods = ['POST'])
122def addVolunteer(eventId):
123 event = Event.get_by_id(eventId)
124 successfullyAddedVolunteer = False
125 usernameList = request.form.getlist("selectedVolunteers[]")
126 successfullyAddedVolunteer = False
127 alreadyAddedList = []
128 addedSuccessfullyList = []
129 errorList = []
131 for user in usernameList:
132 userObj = User.get_by_id(user)
133 successfullyAddedVolunteer = addPersonToEvent(userObj, event)
134 if successfullyAddedVolunteer == "already in":
135 alreadyAddedList.append(userObj.fullName)
136 else:
137 if successfullyAddedVolunteer:
138 addedSuccessfullyList.append(userObj.fullName)
139 else:
140 errorList.append(userObj.fullName)
142 volunteers = ""
143 if alreadyAddedList:
144 volunteers = ", ".join(vol for vol in alreadyAddedList)
145 flash(f"{volunteers} was already added to this event.", "warning")
147 if addedSuccessfullyList:
148 volunteers = ", ".join(vol for vol in addedSuccessfullyList)
149 flash(f"{volunteers} added successfully.", "success")
151 if errorList:
152 volunteers = ", ".join(vol for vol in errorList)
153 flash(f"Error when adding {volunteers} to event.", "danger")
155 if 'ajax' in request.form and request.form['ajax']:
156 return ''
158 return redirect(url_for('admin.manageVolunteersPage', eventID = eventId))
160@admin_bp.route('/rsvpFromWaitlist/<username>/<eventId>', methods = ['POST'])
161def rsvpFromWaitlist(username, eventId):
162 event = Event.get_by_id(eventId)
163 isProgramManager = g.current_user.isProgramManagerFor(event.program)
164 if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager):
165 waitlistUsers = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == username, EventRsvp.event==eventId).execute()
166 if (waitlistUsers):
167 createRsvpLog(event.id, f"Moved {waitlistUsers[0].user.fullName} from waitlist to RSVP.")
168 (EventRsvp.update(rsvpWaitlist = False).where(EventRsvp.event_id == eventId, EventRsvp.user_id == username)).execute()
169 return ""
171@admin_bp.route('/addVolunteersToEvent/<username>/<eventId>/isBanned', methods = ['GET'])
172def isVolunteerBanned(username, eventId):
173 return {"banned":1} if isBannedFromEvent(username, eventId) else {"banned":0}
175@admin_bp.route('/removeVolunteerFromEvent', methods = ['POST'])
176def removeVolunteerFromEvent():
177 user = request.form.get('username')
178 eventID = request.form.get('eventId')
179 if g.current_user.isAdmin:
180 userInRsvpTable = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == user, EventRsvp.event==eventID).execute()
181 if (userInRsvpTable):
182 rsvpUser = userInRsvpTable[0]
183 if rsvpUser.rsvpWaitlist:
184 createRsvpLog(eventID, f"Removed {rsvpUser.user.fullName} from waitlist.")
185 else:
186 createRsvpLog(eventID, f"Removed {rsvpUser.user.fullName} from RSVP list.")
187 (EventParticipant.delete().where(EventParticipant.user==user, EventParticipant.event==eventID)).execute()
188 (EventRsvp.delete().where(EventRsvp.user==user, EventRsvp.event==eventID)).execute()
189 flash("Volunteer successfully removed", "success")
190 return ""
192@admin_bp.route('/addBackgroundCheck', methods = ['POST'])
193def addBackgroundCheck():
194 if g.current_user.isCeltsAdmin:
195 eventData = request.form
196 user = eventData['user']
197 bgStatus = eventData['bgStatus']
198 type = eventData['bgType']
199 dateCompleted = eventData['bgDate']
200 addUserBackgroundCheck(user, type, bgStatus, dateCompleted)
201 return ""
203@admin_bp.route('/deleteBackgroundCheck', methods = ['POST'])
204def deleteBackgroundCheck():
205 if g.current_user.isCeltsAdmin:
206 backgroundData = request.form
207 bgToDelete = BackgroundCheck.get_by_id(backgroundData['bgID'])
208 session["lastDeletedBgCheck"] = bgToDelete.id
209 user = g.current_user
210 deleteUserBackgroundCheck(bgToDelete.id, user)
211 return ""
213@admin_bp.route('/updateProgramManager', methods=["POST"])
214def updateProgramManager():
215 if g.current_user.isCeltsAdmin:
216 data =request.form
217 username = User.get(User.username == data["user_name"])
218 program = Program.get_by_id(data['program_id'])
219 setProgramManager(data["user_name"], data["program_id"], data["action"])
220 createActivityLog(f'{username.firstName} has been {data["action"]}ed as a Program Manager for {program.programName}')
221 return ""
222 else:
223 abort(403)
225@admin_bp.route("/updatePhone", methods=["POST"])
226def updatePhone():
227 newinfo=request.form
228 User.update(phoneNumber=newinfo["phoneNumber"]).where(User.username==newinfo["username"]).execute()
229 return ""