@@ -3,14 +3,34 @@ import { differenceInMonths, subYears } from "date-fns"
33import invariant from "tiny-invariant"
44import type { NTNUGroup } from "../feide/feide-groups-repository"
55import { getLogger } from "@dotkomonline/logger"
6- import { getCurrentUTC } from "@dotkomonline/utils"
7- import type { TZDate } from "@date-fns/tz"
86
97export interface MembershipService {
10- findEstimatedStudyStart (
8+ /**
9+ * Find the approximate semester based on a student's courses against a hard-coded set of courses.
10+ *
11+ * NOTE: The value is 0-indexed.
12+ *
13+ * Master studies begin at semester 6.
14+ *
15+ * @see getCourseStart(semester) in types package
16+ * @see getStudyGrade(semester) in types package
17+ *
18+ * @example
19+ * findEstimatedSemester(...) -> 0 // 1st semester Bachelor (Autumn)
20+ * findEstimatedSemester(...) -> 1 // 2nd semester Bachelor (Spring)
21+ * findEstimatedSemester(...) -> 2 // 3rd semester Bachelor
22+ * findEstimatedSemester(...) -> 3 // 4th semester Bachelor
23+ * findEstimatedSemester(...) -> 4 // 5th semester Bachelor
24+ * findEstimatedSemester(...) -> 5 // 6th semester Bachelor
25+ * findEstimatedSemester(...) -> 6 // 1st semester Master (regardless of prior Bachelor length)
26+ * findEstimatedSemester(...) -> 7 // 2nd semester Master
27+ * findEstimatedSemester(...) -> 8 // 3rd semester Master
28+ * findEstimatedSemester(...) -> 9 // 4th semester Master
29+ */
30+ findEstimatedSemester (
1131 study : "BACHELOR" | "MASTER" ,
12- courses : NTNUGroup [ ]
13- ) : { start : TZDate ; semester : number ; grade : number }
32+ courses : ReadonlyArray < NTNUGroup >
33+ ) : number
1434}
1535
1636const BACHELOR_STUDY_PLAN = [
@@ -44,19 +64,19 @@ const BACHELOR_STUDY_PLAN = [
4464
4565const MASTER_STUDY_PLAN = [
4666 {
47- semester : 0 ,
67+ semester : 6 ,
4868 courses : [ ] ,
4969 } ,
5070 {
51- semester : 1 ,
71+ semester : 7 ,
5272 courses : [ ] ,
5373 } ,
5474 {
55- semester : 2 ,
75+ semester : 8 ,
5676 courses : [ "IT3915" ] ,
5777 } ,
5878 {
59- semester : 3 ,
79+ semester : 9 ,
6080 courses : [ "IT3920" ] ,
6181 } ,
6282] as const
@@ -90,8 +110,7 @@ export function getMembershipService(): MembershipService {
90110 /**
91111 * Find the approximate semester based on a student's courses against a hard-coded set of courses.
92112 */
93- function findEstimatedSemester ( courseSet : StudyPlanCourseSet , studentCourses : NTNUGroup [ ] ) : number {
94- logger . info ( "Searching for applicable membership based on courses %o and study plan %o" , studentCourses , courseSet )
113+ function estimateSemester ( courseSet : StudyPlanCourseSet , studentCourses : ReadonlyArray < NTNUGroup > ) : number {
95114 let largestSemester = 0
96115 for ( let i = 0 ; i < courseSet . length ; i ++ ) {
97116 const semester = courseSet [ i ]
@@ -176,33 +195,9 @@ export function getMembershipService(): MembershipService {
176195 }
177196
178197 return {
179- findEstimatedStudyStart ( study , courses ) {
198+ findEstimatedSemester ( study , courses ) {
180199 const studyPlan = study === "MASTER" ? MASTER_STUDY_PLAN : BACHELOR_STUDY_PLAN
181- const semester = findEstimatedSemester ( studyPlan , courses )
182-
183- // We use Math#round because it will give us the correct year delta:
184- // Year 1 autumn (value 0) : round(0 / 2) = 0 (Start year = current year)
185- // Year 1 spring (value 1): round(1 / 2) = 1 (Start year = current - 1, since spring is in the next calendar year)
186- // Year 2 autumn (value 2) : round(2 / 2) = 1 (Start year = current - 1)
187- // Year 2 spring (value 3): round(3 / 2) = 2 (Start year = current - 2)
188- // ...
189- const yearOffset = Math . round ( semester / 2 )
190- const start = subYears ( getAcademicStart ( getCurrentUTC ( ) ) , yearOffset )
191-
192- // A school year consists of two semesters (Autumn and Spring). So this formula will give us the year:
193- // Year 1 autumn (value 0): floor(0 / 2) + 1 = 1 (Year 1)
194- // Year 1 spring (value 1): floor(1 / 2) + 1 = 1 (Year 1)
195- // Year 2 autumn (value 2): floor(2 / 2) + 1 = 2 (Year 2)
196- // Year 2 spring (value 3): floor(3 / 2) + 1 = 2 (Year 2)
197- // Year 3 autumn (value 4): floor(4 / 2) + 1 = 3 (Year 3)
198- // ...
199- const grade = Math . floor ( semester / 2 ) + 1
200-
201- return {
202- semester,
203- start,
204- grade,
205- }
200+ return estimateSemester ( studyPlan , courses )
206201 } ,
207202 }
208203}
0 commit comments