Coverage for app/logic/userManagement.py: 63%

125 statements  

« prev     ^ index     » next       coverage.py v7.10.2, created at 2026-08-24 19:35 +0000

1import datetime 

2from flask import abort, g, session 

3from playhouse.shortcuts import DoesNotExist, model_to_dict 

4import xlsxwriter 

5 

6 

7from app import app 

8from app.logic.participants import getParticipantsForProgramForAY, getTrainingsForInterestedParticipants 

9from app.logic.users import getProgramInterest 

10from app.logic.volunteerSpreadsheet import makeDataXls 

11from app.models import user 

12from app.models.user import User 

13from app.models.term import Term 

14from app.models.programManager import ProgramManager 

15from app.models.program import Program 

16from app.models.eventTemplate import EventTemplate 

17from app.models.attachmentUpload import AttachmentUpload 

18from app.logic.createLogs import createActivityLog 

19from app.logic.fileHandler import FileHandler 

20 

21def addCeltsAdmin(user): 

22 user = User.get_by_id(user) 

23 user.isCeltsAdmin = True 

24 user.save() 

25 createActivityLog(f'Made {user.firstName} {user.lastName} a CELTS admin member.') 

26 

27def addCeltsStudentStaff(user): 

28 user = User.get_by_id(user) 

29 user.isCeltsStudentStaff = True 

30 user.save() 

31 createActivityLog(f'Made {user.firstName} {user.lastName} a CELTS student staff member.') 

32 

33def addCeltsOperationsTeam(username): 

34 user = User.get_by_id(username) 

35 if not user.isCeltsStudentStaff: 

36 raise ValueError("A user must be CELTS Student Staff before joining the Operations Team.") 

37 user.isCeltsOperationsTeam = True 

38 user.save() 

39 createActivityLog(f"Made {user.fullName} a CELTS operations team member.") 

40 

41def removeCeltsAdmin(user): 

42 user = User.get_by_id(user) 

43 user.isCeltsAdmin = False 

44 user.save() 

45 createActivityLog(f'Removed {user.firstName} {user.lastName} from CELTS admins.') 

46 

47 

48def removeCeltsStudentStaff(user): 

49 user = User.get_by_id(user) 

50 programManagerRoles = list([obj.program.programName for obj in ProgramManager.select(Program).join(Program).where(ProgramManager.user == user)]) 

51 programManagerRoles = ", ".join(programManagerRoles) 

52 ProgramManager.delete().where(ProgramManager.user_id == user).execute() 

53 user.isCeltsStudentStaff = False 

54 user.save() 

55 createActivityLog(f'Removed {user.firstName} {user.lastName} from a CELTS student staff member'+ 

56 (f', and as a manager of {programManagerRoles}.' if programManagerRoles else ".")) 

57 

58def removeCeltsOperationsTeam(user): 

59 user = User.get_by_id(user) 

60 user.isCeltsOperationsTeam = False 

61 user.save() 

62 createActivityLog(f'Removed {user.firstName} {user.lastName} from CELTS operations team members.') 

63 

64def changeProgramInfo(programId, 

65 attachment, 

66 programName= None, 

67 programDescription = None, 

68 partner = None, 

69 contactEmail=None, 

70 contactName= None, 

71 location = None, 

72 instagramUrl = None, 

73 facebookUrl = None, 

74 bereaUrl = None): 

75 

76 

77 """Updates the program info and logs that change""" 

78 program = Program.get_by_id(programId) 

79 if attachment: 

80 addFile: FileHandler = FileHandler(attachment, programId=programId) 

81 addFile.saveFiles() 

82 updatedProgram = Program.update( 

83 { Program.programName:programName, 

84 Program.programDescription: programDescription, 

85 Program.partner: partner, 

86 Program.contactEmail: contactEmail, 

87 Program.contactName: contactName, 

88 Program.defaultLocation: location, 

89 Program.instagramUrl:instagramUrl, 

90 Program.facebookUrl: facebookUrl, 

91 Program.bereaUrl: bereaUrl 

92 } 

93 ).where(Program.id==programId) 

94 updatedProgram.execute() 

95 

96 

97 if programName != program.programName: 

98 createActivityLog(f"{program.programName} Program Name was changed to: {programName}") 

99 if programDescription != program.programDescription: 

100 createActivityLog(f"{program.programName} Description was changed to: {programDescription}") 

101 if partner != program.partner: 

102 createActivityLog(f"{program.programName} Program Partner was changed to: {partner}") 

103 if contactEmail != program.contactEmail: 

104 createActivityLog(f"{program.programName} Contact Email was changed to: {contactEmail}") 

105 if contactName != program.contactName: 

106 createActivityLog(f"{program.programName} Contact Name was changed to: {contactName}") 

107 if location != program.defaultLocation: 

108 createActivityLog(f"{program.programName} Location was changed to: {location}") 

109 

110 

111 return (f'Program email info updated') 

112 

113def getAllowedPrograms(currentUser): 

114 """Returns a list of all visible programs depending on who the current user is.""" 

115 if currentUser.isCeltsAdmin or currentUser.isCeltsOperationsTeam: 

116 return Program.select().order_by(Program.programName) 

117 else: 

118 return Program.select().join(ProgramManager).where(ProgramManager.user==currentUser).order_by(Program.programName) 

119 

120 

121 

122def getAllowedTemplates(currentUser): 

123 """Returns a list of all visible templates depending on who the current user is. If they are not an admin it should always be none.""" 

124 if currentUser.isCeltsAdmin or currentUser.isCeltsOperationsTeam: 

125 return EventTemplate.select().where(EventTemplate.isVisible==True).order_by(EventTemplate.name) 

126 else: 

127 return [] 

128 

129def generateSheetData(program, academicYear, rosterType): 

130 columns = [] 

131 if rosterType == "Interested Volunteers": 

132 columns = ["Username", 

133 "B-number", 

134 "Email", 

135 "Phone", 

136 "First Name", 

137 "Last Name", 

138 "CPO", 

139 "Major", 

140 "Class Level", 

141 "Dietary Restrictions", 

142 "Handbook Signature", 

143 "All Volunteers Training", 

144 "Program Specific Training", 

145 "Background Check", 

146 "Eligible" 

147 ] 

148 query = getTrainingsForInterestedParticipants(program, getProgramInterest(program)) 

149 query = cleanInterestedParticipantsData(query) 

150 return (columns, query) 

151 elif rosterType == "Engaged Volunteers" or rosterType == "Last Year Volunteers": 

152 columns = ["Username", 

153 "B-number", 

154 "Email", 

155 "Phone", 

156 "First Name", 

157 "Last Name", 

158 "CPO", 

159 "Major", 

160 "Class Level", 

161 "Dietary Restrictions", 

162 "Handbook Signature" 

163 ] 

164 if rosterType == "Last Year Volunteers": 

165 academicYear = Term.select().where(Term.academicYear == academicYear).get().previousAcademicYear 

166 query = getParticipantsForProgramForAY(program, academicYear) 

167 query = [model_to_dict(user, only=(User.username, User.bnumber, User.email, User.phoneNumber, User.firstName, User.lastName, User.cpoNumber, User.major, User.rawClassLevel, User.dietRestriction, User.lastHandbookSignature)) for user in query] 

168 query = cleanInterestedParticipantsData(query) 

169 return (columns, query) 

170 

171def cleanInterestedParticipantsData(query): 

172 if type(query) == dict: 

173 for username, userData in query.items(): 

174 # Dictionary of user object and participation data  

175 query[username]["userObj"].major = "Unknown" if not query[username]["userObj"].major else query[username]["userObj"].major 

176 query[username]["userObj"].rawClassLevel = "Unknown" if not query[username]["userObj"].rawClassLevel else query[username]["userObj"].rawClassLevel 

177 query[username]["userObj"].dietRestriction = "Unknown" if not query[username]["userObj"].dietRestriction else query[username]["userObj"].dietRestriction 

178 query[username]["userObj"].lastHandbookSignature = "Not Signed" if not query[username]["userObj"].lastHandbookSignature else query[username]["userObj"].lastHandbookSignature 

179 query[username]["allVolunteer"] = "No" if query[username]["allVolunteer"] == False else "Yes" 

180 query[username]["programSpecific"] = "No" if query[username]["programSpecific"] == False else "Yes" 

181 query[username]["eligible"] = "No" if query[username]["eligible"] == False else "Yes" 

182 del(query[username]["star"]) # Not needed in spreadsheet 

183 else: 

184 # User objects only 

185 for index, userObj in enumerate(query): 

186 userObj["major"] = "Unknown" if not userObj["major"] else userObj["major"] 

187 userObj["rawClassLevel"] = "Unknown" if not userObj["rawClassLevel"] else userObj["rawClassLevel"] 

188 userObj["dietRestriction"] = "Unknown" if not userObj["dietRestriction"] else userObj["dietRestriction"] 

189 userObj["lastHandbookSignature"] = "Not Signed" if not userObj["lastHandbookSignature"] else userObj["lastHandbookSignature"] 

190 query[index] = userObj 

191 return query 

192 

193 

194def createSpreadsheetForRosters(academicYear, program): 

195 try: 

196 program = Program.get_by_id(program) 

197 except DoesNotExist: 

198 raise DoesNotExist 

199 filepath = f'''{app.config['files']['base_path']}/{program.programName.replace(" ", "_")}_rosters_{academicYear}.xlsx''' 

200 workbook = xlsxwriter.Workbook(filepath, {'in_memory': True}) 

201 makeDataXls("Interested Volunteers", generateSheetData(program, academicYear, "Interested Volunteers"), workbook, sheetDesc=f"This worksheet shows all current students who have indicated interest in {program.programName}") 

202 makeDataXls(f"Engaged Volunteers ({academicYear})", generateSheetData(program, academicYear, "Engaged Volunteers"), workbook, sheetDesc=f"This worksheet shows all students who have participated in a service hours earning event in {program.programName}") 

203 makeDataXls(f"Last Year Volunteers", generateSheetData(program, academicYear, "Last Year Volunteers"), workbook, sheetDesc=f"This worksheet shows all current students who participated in a service hours earning event in {program.programName} during the previous academic year") 

204 

205 workbook.close() 

206 return filepath