Coverage for app/models/user.py: 93%

85 statements  

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

1from app.models import * 

2from app.models.term import Term 

3 

4class User(baseModel): 

5 username = CharField(primary_key=True) 

6 bnumber = CharField(unique=True) 

7 email = CharField() 

8 phoneNumber = CharField(null=True) 

9 firstName = CharField() 

10 lastName = CharField() 

11 cpoNumber = CharField(null=False) 

12 isStudent = BooleanField(default=False) 

13 major = CharField(null=True) 

14 rawClassLevel = CharField(null=True) 

15 isFaculty = BooleanField(default=False) 

16 isStaff = BooleanField(default=False) 

17 isCeltsAdmin = BooleanField(default=False) 

18 isCeltsStudentStaff = BooleanField(default=False) 

19 isCeltsOperationsTeam = BooleanField(default=False) # A user MUST be a CELTS Student Staff member to be a CELTS Operations Team member. 

20 dietRestriction = TextField(null=True) 

21 minorInterest = BooleanField(null=True) 

22 hasGraduated = BooleanField(default=False) 

23 declaredMinor = BooleanField(default=False) 

24 lastHandbookSignature = DateTimeField(null=True) 

25 signatureTerm = ForeignKeyField(Term, null = True) 

26 

27 # override BaseModel's __init__ so that we can set up an instance attribute for cache 

28 def __init__(self,*args, **kwargs): 

29 super().__init__(*args,**kwargs) 

30 

31 self._pmCache = {} 

32 self._bsCache = None 

33 self._laborCache = None 

34 self._isProgramManagerCache = None 

35 

36 @property 

37 def processedClassLevel(self): 

38 if self.isAlumni: 

39 return "Alumni" 

40 return self.rawClassLevel or "Not Enrolled" 

41 

42 @property 

43 def isAlumni(self): 

44 return self.hasGraduated or self.rawClassLevel == "Graduating" 

45 

46 @property 

47 def isCurrentlyEnrolled(self): 

48 return self.isStudent and not self.isAlumni 

49 

50 @property 

51 def isAdmin(self): 

52 return (self.isCeltsAdmin or self.isCeltsStudentStaff) 

53 

54 @property 

55 def isBonnerScholar(self): 

56 from app.models.bonnerCohort import BonnerCohort 

57 if self._bsCache is None: 

58 # TODO should we exclude users who are banned from Bonner here? 

59 self._bsCache = BonnerCohort.select().where(BonnerCohort.user == self).exists() 

60 

61 return self._bsCache 

62 

63 @property 

64 def hasCurrentCeltsLabor(self): 

65 if self._laborCache is None: 

66 from app.models.celtsLabor import CeltsLabor 

67 from app.models.term import Term 

68 self._laborCache = (CeltsLabor.select() 

69 .join(Term) 

70 .where(CeltsLabor.user == self, 

71 CeltsLabor.term.isCurrentTerm == True) 

72 .exists()) 

73 return self._laborCache 

74 

75 @property 

76 def fullName(self): 

77 return f"{self.firstName} {self.lastName}" 

78 

79 def addProgramManager(self, program): 

80 # Makes a user a Program Manager 

81 from app.models.programManager import ProgramManager 

82 ProgramManager.create(user = self, program = program) 

83 

84 return (f' {self} added as Program Manager') 

85 

86 def removeProgramManager(self, program): 

87 # Removes an existing Program Manager from being a Program Manager 

88 from app.models.programManager import ProgramManager 

89 ProgramManager.delete().where(ProgramManager.user == self, ProgramManager.program == program).execute() 

90 

91 return (f'{self} removed from Program Manager') 

92 

93 def isProgramManagerFor(self, program): 

94 # Looks to see who is the Program Manager for a program 

95 from app.models.programManager import ProgramManager # Must defer import until now to avoid circular reference 

96 if not program: 

97 return False 

98 

99 if program not in self._pmCache: 

100 self._pmCache[program] = ProgramManager.select().where(ProgramManager.user == self, ProgramManager.program == program).exists() 

101 

102 return self._pmCache[program] 

103 

104 def isProgramManagerForEvent(self, event): 

105 # Looks to see who the Program Manager for a specific event is 

106 return self.isProgramManagerFor(event.program) 

107 

108 def canManageProgram(self, program): 

109 return self.isCeltsAdmin or self.isCeltsOperationsTeam or self.isProgramManagerFor(program) 

110 

111 @property 

112 def isProgramManager(self): 

113 from app.models.programManager import ProgramManager 

114 if self._isProgramManagerCache is None: 

115 self._isProgramManagerCache = ProgramManager.select().where(ProgramManager.user == self).exists() 

116 

117 return self._isProgramManagerCache 

118 

119