Coverage for app/controllers/admin/volunteers.py: 26%

149 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-06-27 19:26 +0000

1from flask import request, render_template, redirect, url_for, flash, abort, g, json, jsonify 

2from peewee import DoesNotExist, JOIN 

3from playhouse.shortcuts import model_to_dict 

4from app.controllers.admin import admin_bp 

5from app.models.event import Event 

6from app.models.program import Program 

7from app.models.user import User 

8from app.models.eventParticipant import EventParticipant 

9from app.models.emergencyContact import EmergencyContact 

10from app.logic.searchUsers import searchUsers 

11from app.logic.volunteers import updateEventParticipants, getEventLengthInHours, addUserBackgroundCheck, setProgramManager 

12from app.logic.participants import trainedParticipants, addPersonToEvent, getParticipationStatusForTrainings, sortParticipantsByStatus 

13from app.logic.events import getPreviousRecurringEventData, getEventRsvpCount 

14from app.models.eventRsvp import EventRsvp 

15from app.models.backgroundCheck import BackgroundCheck 

16from app.logic.createLogs import createActivityLog, createRsvpLog 

17from app.logic.users import getBannedUsers, isBannedFromEvent 

18 

19 

20@admin_bp.route('/searchVolunteers/<query>', methods = ['GET']) 

21def getVolunteers(query): 

22 '''Accepts user input and queries the database returning results that matches user search''' 

23 

24 return json.dumps(searchUsers(query)) 

25 

26@admin_bp.route('/event/<eventID>/manage_volunteers', methods=['GET', 'POST']) 

27def manageVolunteersPage(eventID): 

28 """ 

29 Controller that handles POST and GET requests regarding the Manage Volunteers page. 

30 

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

32 updateEventParticipants on the form. 

33 

34 GET: retrieves all necessary participant lists and dictionaries and categorizes 

35 the participants/volunteers into their respective participation statuses. Then  

36 renders the manageVolunteers.html template. 

37 """ 

38 try: 

39 event = Event.get_by_id(eventID) 

40 except DoesNotExist as e: 

41 print(f"No event found for {eventID}", e) 

42 abort(404) 

43 

44 # ------------ POST request ------------ 

45 if request.method == "POST": 

46 volunteerUpdated = updateEventParticipants(request.form) 

47 

48 # error handling depending on the boolean returned from updateEventParticipants 

49 if volunteerUpdated: 

50 flash("Volunteer table succesfully updated", "success") 

51 else: 

52 flash("Error adding volunteer", "danger") 

53 return redirect(url_for("admin.manageVolunteersPage", eventID=eventID)) 

54 

55 # ------------ GET request ------------ 

56 elif request.method == "GET": 

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

58 abort(403) 

59 

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

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

62 

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

64 

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

66 

67 allRelevantUsers = [participant.user for participant in (eventParticipants + eventNonAttendedData + eventWaitlistData)] 

68 

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 recurringVolunteers = getPreviousRecurringEventData(event.recurringId) 

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 recurringVolunteers = recurringVolunteers, 

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 eventData = request.form 

206 bgToDelete = BackgroundCheck.get_by_id(eventData['bgID']) 

207 BackgroundCheck.delete().where(BackgroundCheck.id == bgToDelete).execute() 

208 return "" 

209 

210@admin_bp.route('/updateProgramManager', methods=["POST"]) 

211def updateProgramManager(): 

212 if g.current_user.isCeltsAdmin: 

213 data =request.form 

214 username = User.get(User.username == data["user_name"]) 

215 program = Program.get_by_id(data['program_id']) 

216 setProgramManager(data["user_name"], data["program_id"], data["action"]) 

217 createActivityLog(f'{username.firstName} has been {data["action"]}ed as a Program Manager for {program.programName}') 

218 return "" 

219 else: 

220 abort(403) 

221 

222@admin_bp.route("/updatePhone", methods=["POST"]) 

223def updatePhone(): 

224 newinfo=request.form 

225 User.update(phoneNumber=newinfo["phoneNumber"]).where(User.username==newinfo["username"]).execute() 

226 return ""