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

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 

19 

20 

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''' 

24 

25 return json.dumps(searchUsers(query)) 

26 

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. 

31 

32 POST: updates the event participants for a particular event by calling  

33 updateEventParticipants on the form. 

34 

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) 

44 

45 # ------------ POST request ------------ 

46 if request.method == "POST": 

47 volunteerUpdated = updateEventParticipants(request.form) 

48 

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)) 

55 

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) 

60 

61 # ------- Grab the different lists of participants ------- 

62 trainedParticipantsForProgramAndTerm = trainedParticipants(event.program, event.term) 

63 

64 bannedUsersForProgram = [bannedUser.user for bannedUser in getBannedUsers(event.program)] 

65 

66 eventNonAttendedData, eventWaitlistData, eventVolunteerData, eventParticipants = sortParticipantsByStatus(event) 

67 

68 allRelevantUsers = list(set(participant.user for participant in (eventParticipants + eventNonAttendedData + eventWaitlistData + eventVolunteerData))) 

69 # ----------- Get miscellaneous data ----------- 

70 

71 participationStatusForTrainings = getParticipationStatusForTrainings(event.program, allRelevantUsers, event.term) 

72 

73 eventLengthInHours = getEventLengthInHours(event.timeStart, event.timeEnd, event.startDate) 

74 

75 repeatingVolunteers = getPreviousSeriesEventData(event.seriesId) 

76 

77 currentRsvpAmount = getEventRsvpCount(event.id) 

78 

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) 

91 

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) 

99 

100 if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event))): 

101 abort(403) 

102 

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)) 

109 

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 ])) 

112 

113 return render_template("/events/volunteerDetails.html", 

114 waitlistUser = waitlistUser, 

115 attendedUser= eventParticipantData, 

116 rsvpUser= rsvpUser, 

117 event = event) 

118 

119 

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 = [] 

129 

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) 

140 

141 volunteers = "" 

142 if alreadyAddedList: 

143 volunteers = ", ".join(vol for vol in alreadyAddedList) 

144 flash(f"{volunteers} was already added to this event.", "warning") 

145 

146 if addedSuccessfullyList: 

147 volunteers = ", ".join(vol for vol in addedSuccessfullyList) 

148 flash(f"{volunteers} added successfully.", "success") 

149 

150 if errorList: 

151 volunteers = ", ".join(vol for vol in errorList) 

152 flash(f"Error when adding {volunteers} to event.", "danger") 

153 

154 if 'ajax' in request.form and request.form['ajax']: 

155 return '' 

156 

157 return redirect(url_for('admin.manageVolunteersPage', eventID = eventId)) 

158 

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 "" 

169 

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} 

173 

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 "" 

190 

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 "" 

201 

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 "" 

211 

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) 

223 

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 ""