Coverage for app/logic/transcript.py: 100%

38 statements  

« prev     ^ index     » next       coverage.py v7.10.2, created at 2026-04-07 20:25 +0000

1from peewee import fn 

2from collections import defaultdict 

3 

4from app.models.course import Course 

5from app.models.courseParticipant import CourseParticipant 

6from app.models.program import Program 

7from app.models.programBan import ProgramBan 

8from app.models.courseInstructor import CourseInstructor 

9from app.models.user import User 

10from app.models.term import Term 

11from app.models.eventParticipant import EventParticipant 

12from app.models.event import Event 

13 

14def getProgramTranscript(username): 

15 """ 

16 Returns a dictionary with programs as keys and a list of service or bonner events and hours earned as values for the given user. 

17 """ 

18 # Add up hours earned in a term for each program they've participated in 

19 

20 EventData = (Event.select(Event, fn.SUM(EventParticipant.hoursEarned).alias("hoursEarned")) 

21 .join(EventParticipant).switch() 

22 .join(Program) 

23 .where(EventParticipant.user == username, 

24 Event.isService | Program.isBonnerScholars, 

25 Event.deletionDate == None, 

26 Event.isCanceled == False) 

27 .group_by(Event.program, Event.term) 

28 .order_by(Event.term) 

29 .having(fn.SUM(EventParticipant.hoursEarned > 0))) 

30 

31 # Fetch all ProgramBan objects for the user 

32 bannedProgramsForParticipant = ProgramBan.select().where(ProgramBan.user == username) 

33 

34 # Create a set of program IDs to remove from transcript 

35 programsToRemoveFromTranscript = {bannedProgram.program_id for bannedProgram in bannedProgramsForParticipant if bannedProgram.removeFromTranscript} 

36 transcriptData = defaultdict(list) 

37 

38 # Iterate through EventData and populate transcriptData 

39 for event in EventData: 

40 if event.program.id not in programsToRemoveFromTranscript: # Check if program is not in programs to be removed from transcript 

41 transcriptData[event.program].append([event.term.description, event.hoursEarned]) 

42 

43 return dict(transcriptData) 

44 

45def getZeroHourEvents(username): 

46 """ 

47 Returns a list of events with zero hours earned for the given user, 

48 excluding deleted and canceled events. 

49 """ 

50 zeroHourEvents = (Event.select(Event, Program, Term) 

51 .join(EventParticipant) 

52 .switch(Event) 

53 .join(Program) 

54 .switch(Event) 

55 .join(Term) 

56 .where(EventParticipant.user == username, 

57 EventParticipant.hoursEarned == 0, 

58 Event.deletionDate == None, 

59 Event.isCanceled == False) 

60 .order_by(Event.term)) 

61 

62 return list(zeroHourEvents) 

63 

64def getSlCourseTranscript(username): 

65 """ 

66 Returns a SLCourse query object containing all the training events for 

67 current user. 

68 """ 

69 

70 slCourses = (Course.select(Course, fn.SUM(CourseParticipant.hoursEarned).alias("hoursEarned")) 

71 .join(CourseParticipant, on=(Course.id == CourseParticipant.course)) 

72 .where(CourseParticipant.user == username) 

73 .group_by(Course.courseName, Course.term)) 

74 

75 return slCourses 

76 

77def getTotalHours(username): 

78 """ 

79 Get the toal hours from events and courses combined. 

80 """ 

81 bannedAndTranscriptsRemoved = ProgramBan.select().where((ProgramBan.user == username) and (ProgramBan.unbanNote.is_null(True)) and (ProgramBan.removeFromTranscript == 1)) 

82 transcriptsRemovedIdList = [program.program_id for program in bannedAndTranscriptsRemoved] 

83 

84 eventHours = (EventParticipant.select(fn.SUM(EventParticipant.hoursEarned)) 

85 .join(Event, on=(EventParticipant.event == Event.id)) 

86 .where((EventParticipant.user == username) & (Event.program_id.not_in(transcriptsRemovedIdList)) & (Event.deletionDate == None))).scalar() 

87 

88 

89 

90 courseHours = (CourseParticipant.select(fn.SUM(CourseParticipant.hoursEarned)) 

91 .where(CourseParticipant.user == username)).scalar() 

92 

93 allHours = {"totalEventHours": (eventHours or 0), 

94 "totalCourseHours": (courseHours or 0), 

95 "totalHours": (eventHours or 0) + (courseHours or 0)} 

96 return allHours 

97 

98def getStartYear(username): 

99 """ 

100 Returns the users start term for participation in the CELTS organization 

101 """ 

102 

103 startDate = (EventParticipant.select(Term.year) 

104 .join(Event) 

105 .join(Term).where(EventParticipant.user == username) 

106 + CourseParticipant.select(Term.year) 

107 .join(Course) 

108 .join(Term) 

109 .where(CourseParticipant.user == username) 

110 ).order_by(Event.term.year).first() 

111 

112 if startDate: 

113 return startDate.event.term.year 

114 

115 return "N/A"