[Meta] Add course code to credits and enrollments of students

This commit is contained in:
Aaro Koivukangas
2026-09-21 15:24:21 +03:00
committed by Aaro Koivukangas
parent 6d169a3455
commit 172081468a
7 changed files with 44 additions and 43 deletions
@@ -1,6 +1,6 @@
import { Op } from 'sequelize' import { Op } from 'sequelize'
import { Credit, Enrollment, SISStudyRight, SISStudyRightElement, Student, Studyplan } from '@oodikone/shared/models' import { SISStudyRight, SISStudyRightElement, Student, Studyplan } from '@oodikone/shared/models'
import { Tag, TagStudent } from '@oodikone/shared/models/kone' import { Tag, TagStudent } from '@oodikone/shared/models/kone'
import { EnrollmentState } from '@oodikone/shared/types' import { EnrollmentState } from '@oodikone/shared/types'
import { enrollmentTimeDateThreshold } from '@oodikone/shared/util' import { enrollmentTimeDateThreshold } from '@oodikone/shared/util'
@@ -14,6 +14,7 @@ import {
SISStudyRightElementModel, SISStudyRightElementModel,
} from '../../models' } from '../../models'
import { TagModel, TagStudentModel } from '../../models/kone' import { TagModel, TagStudentModel } from '../../models/kone'
import { StudentCredit, StudentEnrollment } from '@oodikone/shared/types/studentData'
export type StudentTags = TagStudent & { export type StudentTags = TagStudent & {
tag: Pick<Tag, 'tag_id' | 'tagname' | 'personal_user_id'> tag: Pick<Tag, 'tag_id' | 'tagname' | 'personal_user_id'>
@@ -46,17 +47,21 @@ export const getStudentTagMap = async (studyRights: string[], studentNumbers: st
return studentTagMap return studentTagMap
} }
export type StudentEnrollment = Pick<
Enrollment,
'course_id' | 'state' | 'enrollment_date_time' | 'semestercode' | 'studentnumber' | 'studyright_id'
>
export const getEnrollments = ( export const getEnrollments = (
studentNumbers: string[], studentNumbers: string[],
startDate: string, startDate: string,
endDate: string endDate: string
): Promise<StudentEnrollment[]> => ): Promise<StudentEnrollment[]> =>
EnrollmentModel.findAll({ EnrollmentModel.findAll({
attributes: ['course_id', 'state', 'enrollment_date_time', 'semestercode', 'studentnumber', 'studyright_id'], attributes: [
'course_id',
'course_code',
'state',
'enrollment_date_time',
'semestercode',
'studentnumber',
'studyright_id',
],
where: { where: {
studentnumber: { studentnumber: {
[Op.in]: studentNumbers, [Op.in]: studentNumbers,
@@ -185,19 +190,6 @@ export const getStudents = (studentNumbers: string[]): Promise<Array<StudentData
}, },
}).then(data => data.map(x => x.get({ plain: true }))) }).then(data => data.map(x => x.get({ plain: true })))
export type StudentCredit = Pick<
Credit,
| 'grade'
| 'credits'
| 'credittypecode'
| 'attainment_date'
| 'isStudyModule'
| 'student_studentnumber'
| 'course_id'
| 'language'
| 'studyright_id'
>
export const getCredits = async ( export const getCredits = async (
studentNumbers: string[], studentNumbers: string[],
startDate: string, startDate: string,
@@ -213,6 +205,7 @@ export const getCredits = async (
'isStudyModule', 'isStudyModule',
'student_studentnumber', 'student_studentnumber',
'course_id', 'course_id',
'course_code',
'language', 'language',
'studyright_id', 'studyright_id',
], ],
@@ -4,8 +4,6 @@ import { getCriteria } from '../studyProgramme/studyProgrammeCriteria'
import { getCourseDetails } from '../courses' import { getCourseDetails } from '../courses'
import { formatStudentForAPI } from './formatStatisticsForApi' import { formatStudentForAPI } from './formatStatisticsForApi'
import { import {
type StudentEnrollment,
type StudentCredit,
type StudentTags, type StudentTags,
getStudents, getStudents,
getEnrollments, getEnrollments,
@@ -13,6 +11,7 @@ import {
getStudyRightElementsForStudyRight, getStudyRightElementsForStudyRight,
} from './getStudentData' } from './getStudentData'
import { getCourseGroupIds, getOptionsForStudents } from './shared' import { getCourseGroupIds, getOptionsForStudents } from './shared'
import { StudentCredit, StudentEnrollment } from '@oodikone/shared/types/studentData'
export type OptimizedStatisticsQuery = { export type OptimizedStatisticsQuery = {
userId: string userId: string
@@ -55,7 +55,7 @@ export const CustomPopulationContent = ({
useEffect(() => { useEffect(() => {
setStudentAmountLimit(Math.round(filteredStudents.length ? filteredStudents.length * 0.3 : 0)) setStudentAmountLimit(Math.round(filteredStudents.length ? filteredStudents.length * 0.3 : 0))
}, [filteredStudents.length]) }, [filteredStudents.length, setStudentAmountLimit])
const onStudentAmountLimitChange = value => { const onStudentAmountLimitChange = value => {
setStudentAmountLimit(Number.isNaN(Number(value)) ? studentAmountLimit : Number(value)) setStudentAmountLimit(Number.isNaN(Number(value)) ? studentAmountLimit : Number(value))
@@ -123,7 +123,7 @@ export const CustomPopulationContent = ({
showBachelorAndMaster: false, showBachelorAndMaster: false,
includePrimaryProgramme: false, includePrimaryProgramme: false,
coursecodes: [], courseIds: [],
from: undefined, from: undefined,
to: undefined, to: undefined,
}) })
@@ -78,6 +78,7 @@ export const formatPopulationData = <T extends RequiredFields>(
return { return {
course_id: credit.course_id, course_id: credit.course_id,
course_code: credit.course_code,
date: credit.attainment_date, date: credit.attainment_date,
passed, passed,
grade: passed ? credit.grade : 'Hyl.', grade: passed ? credit.grade : 'Hyl.',
+4 -18
View File
@@ -1,4 +1,4 @@
import { Credit, Enrollment, Course } from '../models' import { Course } from '../models'
import { import {
Name, Name,
ProgrammeModuleWithRelevantAttributes, ProgrammeModuleWithRelevantAttributes,
@@ -8,7 +8,7 @@ import {
ProgressCriteria, ProgressCriteria,
Unification, Unification,
} from '../types' } from '../types'
import { FormattedStudent } from '../types/studentData' import { FormattedStudent, StudentCredit, StudentEnrollment } from '../types/studentData'
export type CourseStats = Pick<Course, 'code' | 'id' | 'groupId' | 'name' | 'isStudyModule' | 'substitutionGroups'> export type CourseStats = Pick<Course, 'code' | 'id' | 'groupId' | 'name' | 'isStudyModule' | 'substitutionGroups'>
@@ -60,22 +60,8 @@ export type PopulationCourseStats = {
// One row per groupId (isPrimary=true course for that group) // One row per groupId (isPrimary=true course for that group)
courses: CourseStats[] courses: CourseStats[]
idToGroupIdMap: Record<string, string> idToGroupIdMap: Record<string, string>
enrollments: Pick< enrollments: (StudentEnrollment & { studentnumber: string })[]
Enrollment, credits: StudentCredit[]
'course_id' | 'state' | 'enrollment_date_time' | 'semestercode' | 'studentnumber' | 'studyright_id'
>[]
credits: Pick<
Credit,
| 'grade'
| 'credits'
| 'credittypecode'
| 'attainment_date'
| 'isStudyModule'
| 'student_studentnumber'
| 'course_id'
| 'language'
| 'studyright_id'
>[]
} }
// populationstatistics // populationstatistics
+2
View File
@@ -70,6 +70,7 @@ export const createStudyRight = (overrides: Partial<StudentStudyRight> = {}): St
export const createCourse = (overrides: Partial<StudentCourse> = {}): StudentCourse => ({ export const createCourse = (overrides: Partial<StudentCourse> = {}): StudentCourse => ({
course_id: 'hy-CU-000000001-2024-08-01', course_id: 'hy-CU-000000001-2024-08-01',
course_code: 'MAT001',
date: new Date('2024-08-01'), date: new Date('2024-08-01'),
passed: true, passed: true,
grade: '5', grade: '5',
@@ -95,6 +96,7 @@ export const createEnrollment = (
overrides: Partial<FormattedStudent['enrollments'][number]> = {} overrides: Partial<FormattedStudent['enrollments'][number]> = {}
): FormattedStudent['enrollments'][number] => ({ ): FormattedStudent['enrollments'][number] => ({
course_id: 'hy-CU-000000001-2024-08-01', course_id: 'hy-CU-000000001-2024-08-01',
course_code: 'MAT001',
state: EnrollmentState.ENROLLED, state: EnrollmentState.ENROLLED,
enrollment_date_time: new Date('2024-08-01'), enrollment_date_time: new Date('2024-08-01'),
semestercode: 149, semestercode: 149,
+22 -2
View File
@@ -1,4 +1,4 @@
import type { Enrollment, SISStudyRight, SISStudyRightElement, Student, Studyplan } from '../models' import type { Credit, Enrollment, SISStudyRight, SISStudyRightElement, Student, Studyplan } from '../models'
import type { Tag, TagStudent } from '../models/kone' import type { Tag, TagStudent } from '../models/kone'
import type { CriteriaYear, CreditTypeCode, Name, ProgrammeModule } from '../types' import type { CriteriaYear, CreditTypeCode, Name, ProgrammeModule } from '../types'
@@ -106,6 +106,7 @@ export type StudentPageStudent = {
export type StudentCourse = { export type StudentCourse = {
course_id: string course_id: string
course_code: string
date: Date date: Date
passed: boolean passed: boolean
grade: string grade: string
@@ -116,6 +117,25 @@ export type StudentCourse = {
studyright_id: string studyright_id: string
} }
export type StudentCredit = Pick<
Credit,
| 'grade'
| 'credits'
| 'credittypecode'
| 'attainment_date'
| 'isStudyModule'
| 'student_studentnumber'
| 'course_id'
| 'course_code'
| 'language'
| 'studyright_id'
>
export type StudentEnrollment = Pick<
Enrollment,
'course_id' | 'course_code' | 'state' | 'enrollment_date_time' | 'semestercode' | 'studentnumber' | 'studyright_id'
>
export type FormattedStudent = { export type FormattedStudent = {
obfuscated?: true obfuscated?: true
@@ -146,5 +166,5 @@ export type FormattedStudent = {
studyRights: StudentStudyRight[] studyRights: StudentStudyRight[]
studyplans: StudentStudyPlan[] studyplans: StudentStudyPlan[]
courses: StudentCourse[] courses: StudentCourse[]
enrollments: Pick<Enrollment, 'course_id' | 'state' | 'enrollment_date_time' | 'semestercode' | 'studyright_id'>[] enrollments: Omit<StudentEnrollment, 'studentnumber'>[]
} }