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

81 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 

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 eventFlagsMatrix = {'isAllVolunteerTraining': {'isAllVolunteerTraining', 

33 'isTraining'}, 

34 'isCeltsTraining': {'isCeltsTraining', 

35 'isLaborOnly', 

36 'isTraining'}, 

37 'isLaborOnly': {'isLaborOnly', 

38 'isCeltsTraining', 

39 'isTraining'}, 

40 'allowsLabor': {'allowsLabor', 

41 'isTraining', 

42 'isService', 

43 'isEngagement'}, 

44 'isTraining': {'isTraining', 

45 'isAllVolunteerTraining', 

46 'isCeltsTraining', 

47 'isLaborOnly', 

48 'allowsLabor'}, 

49 'isService': {'isService', 

50 'allowsLabor'}, 

51 'isEngagement': {'isEngagement', 

52 'allowsLabor'} 

53 } 

54 

55 _spCache = "Empty" 

56 

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

58 """ 

59 Overrides the default Peewee save method.  

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

61 """ 

62 if self.checkFlags(): 

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

64 else: 

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

66 

67 def __str__(self): 

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

69 

70 def checkFlags(self): 

71 """ 

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

73 """ 

74 setFlags = [] 

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

76 if self.eventFlagsMatrix.get(attribute): 

77 if getattr(self, attribute): 

78 setFlags.append(attribute) 

79 for setFlag in setFlags: 

80 allowedFlags = self.eventFlagsMatrix[setFlag] 

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

82 return False 

83 return True 

84 

85 @property 

86 def isDeleted(self): 

87 return self.deletionDate is not None 

88 

89 @property 

90 def noProgram(self): 

91 return not self.program_id 

92 

93 @property 

94 def isPastStart(self): 

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

96 

97 @property 

98 def isPastEnd(self): 

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

100 

101 @property 

102 def isFirstRepeatingEvent(self): 

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

104 return firstRepeatingEvent.id == self.id 

105 

106 @property 

107 def relativeTime(self): 

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

109 

110 secondsFromNow = relativeTime.seconds 

111 minutesFromNow = secondsFromNow // 60 

112 hoursFromNow = minutesFromNow // 60 

113 daysFromNow = relativeTime.days 

114 if self.isPastStart: 

115 return "" 

116 elif (daysFromNow): 

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

118 elif hoursFromNow: 

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

120 elif minutesFromNow: 

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

122 else: 

123 return f"happening now" 

124 

125