Coverage for app/models/event.py: 88%

84 statements  

« prev     ^ index     » next       coverage.py v7.10.2, created at 2026-09-22 13:52 +0000

1from app.models import * 

2from app.models.term import Term 

3from app.models.program import Program 

4from datetime import datetime 

5 

6class Event(baseModel): 

7 name = CharField() 

8 term = ForeignKeyField(Term) 

9 description = TextField() 

10 timeStart = TimeField() 

11 timeEnd = TimeField() 

12 location = CharField() 

13 isFoodProvided = BooleanField(default=False) 

14 allowsLabor = BooleanField(default=False) # Event has some labor students working in addition to volunteers 

15 isLaborOnly = BooleanField(default=False) # Event is a labor meeting, specifically for labor students only  

16 isTraining = BooleanField(default=False) # Event is a training for a Program (required by volunteers to earn service hours in that program) 

17 isAllVolunteerTraining = BooleanField(default=False) # Event is an All Volunteers Training (required to earn any service hours) 

18 isCeltsTraining = BooleanField(default=False) # Event is a CELTS labor training (required by all CELTS labor students) 

19 isRsvpRequired = BooleanField(default=False) 

20 isService = BooleanField(default=False) 

21 isEngagement = BooleanField(default=False) 

22 rsvpLimit = IntegerField(null=True) 

23 startDate = DateField() 

24 seriesId = IntegerField(null=True) 

25 isRepeating = BooleanField(default=False) 

26 contactEmail = CharField(null=True) 

27 contactName = CharField(null=True) 

28 program = ForeignKeyField(Program) 

29 isCanceled = BooleanField(default=False) 

30 deletionDate = DateTimeField(null=True) 

31 deletedBy = TextField(null=True) 

32 campusGroupsId = IntegerField(null=True) 

33 campusGroupsURL = CharField(null=True) 

34 isCampusGroupsSynced = BooleanField(default=False) 

35 eventFlagsMatrix = {'isAllVolunteerTraining': {'isAllVolunteerTraining', 

36 'isTraining'}, 

37 'isCeltsTraining': {'isCeltsTraining', 

38 'isLaborOnly', 

39 'isTraining'}, 

40 'isLaborOnly': {'isLaborOnly', 

41 'isCeltsTraining', 

42 'isTraining'}, 

43 'allowsLabor': {'allowsLabor', 

44 'isTraining', 

45 'isService', 

46 'isEngagement'}, 

47 'isTraining': {'isTraining', 

48 'isAllVolunteerTraining', 

49 'isCeltsTraining', 

50 'isLaborOnly', 

51 'allowsLabor'}, 

52 'isService': {'isService', 

53 'allowsLabor'}, 

54 'isEngagement': {'isEngagement', 

55 'allowsLabor'} 

56 } 

57 

58 _spCache = "Empty" 

59 

60 def save(self, *args, **kwargs): 

61 """ 

62 Overrides the default Peewee save method.  

63 NOTE: This method is not called when using Model.update() 

64 """ 

65 if self.checkFlags(): 

66 return super().save(*args, **kwargs) 

67 else: 

68 raise IntegrityError("This combination of options is not allowed") 

69 

70 def __str__(self): 

71 return f"{self.id}: {self.description}" 

72 

73 def checkFlags(self): 

74 """ 

75 Checks the eventFlagsMatrix to ensure the user is only picking a combination of flags that are allowed. 

76 """ 

77 setFlags = [] 

78 for attribute in self._meta.fields.keys(): 

79 if self.eventFlagsMatrix.get(attribute): 

80 if getattr(self, attribute): 

81 setFlags.append(attribute) 

82 for setFlag in setFlags: 

83 allowedFlags = self.eventFlagsMatrix[setFlag] 

84 if not all(flag in allowedFlags for flag in setFlags): 

85 return False 

86 return True 

87 

88 @property 

89 def isDeleted(self): 

90 return self.deletionDate is not None 

91 

92 @property 

93 def noProgram(self): 

94 return not self.program_id 

95 

96 @property 

97 def isPastStart(self): 

98 return datetime.now() >= datetime.combine(self.startDate, self.timeStart) 

99 

100 @property 

101 def isPastEnd(self): 

102 return datetime.now() >= datetime.combine(self.startDate, self.timeEnd) 

103 

104 @property 

105 def isFirstRepeatingEvent(self): 

106 firstRepeatingEvent = Event.select().where(Event.seriesId==self.seriesId).order_by(Event.id).get() 

107 return firstRepeatingEvent.id == self.id 

108 

109 @property 

110 def relativeTime(self): 

111 relativeTime = datetime.combine(self.startDate, self.timeStart) - datetime.now() 

112 

113 secondsFromNow = relativeTime.seconds 

114 minutesFromNow = secondsFromNow // 60 

115 hoursFromNow = minutesFromNow // 60 

116 daysFromNow = relativeTime.days 

117 if self.isPastStart: 

118 return "" 

119 elif (daysFromNow): 

120 return f"{daysFromNow} day" + ("s" if daysFromNow > 1 else "") 

121 elif hoursFromNow: 

122 return f"{hoursFromNow} hour" + ("s" if hoursFromNow > 1 else "") 

123 elif minutesFromNow: 

124 return f"{minutesFromNow} minute" + ("s" if minutesFromNow > 1 else "") 

125 else: 

126 return f"happening now" 

127 

128