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

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 = [participant.user for participant in (eventParticipants + eventNonAttendedData + eventWaitlistData)] 

69 

70 # ----------- Get miscellaneous data ----------- 

71 

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

73 

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

75 

76 repeatingVolunteers = getPreviousSeriesEventData(event.seriesId) 

77 

78 currentRsvpAmount = getEventRsvpCount(event.id) 

79 

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) 

92 

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) 

100 

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

102 abort(403) 

103 

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

110 

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

113 

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

115 waitlistUser = waitlistUser, 

116 attendedUser= eventParticipantData, 

117 rsvpUser= rsvpUser, 

118 event = event) 

119 

120 

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

130 

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) 

141 

142 volunteers = "" 

143 if alreadyAddedList: 

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

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

146 

147 if addedSuccessfullyList: 

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

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

150 

151 if errorList: 

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

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

154 

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

156 return '' 

157 

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

159 

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

170 

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} 

174 

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

191 

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

202 

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

212 

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) 

224 

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