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
« 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
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)
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)
31 self._pmCache = {}
32 self._bsCache = None
33 self._laborCache = None
34 self._isProgramManagerCache = None
36 @property
37 def processedClassLevel(self):
38 if self.isAlumni:
39 return "Alumni"
40 return self.rawClassLevel or "Not Enrolled"
42 @property
43 def isAlumni(self):
44 return self.hasGraduated or self.rawClassLevel == "Graduating"
46 @property
47 def isCurrentlyEnrolled(self):
48 return self.isStudent and not self.isAlumni
50 @property
51 def isAdmin(self):
52 return (self.isCeltsAdmin or self.isCeltsStudentStaff)
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()
61 return self._bsCache
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
75 @property
76 def fullName(self):
77 return f"{self.firstName} {self.lastName}"
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)
84 return (f' {self} added as Program Manager')
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()
91 return (f'{self} removed from Program Manager')
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
99 if program not in self._pmCache:
100 self._pmCache[program] = ProgramManager.select().where(ProgramManager.user == self, ProgramManager.program == program).exists()
102 return self._pmCache[program]
104 def isProgramManagerForEvent(self, event):
105 # Looks to see who the Program Manager for a specific event is
106 return self.isProgramManagerFor(event.program)
108 def canManageProgram(self, program):
109 return self.isCeltsAdmin or self.isCeltsOperationsTeam or self.isProgramManagerFor(program)
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()
117 return self._isProgramManagerCache