src/module/scheincriteria/scheincriteria.service.ts
Methods |
|
constructor(studentService: StudentService, sheetService: SheetService, scheinexamService: ScheinexamService, tutorialService: TutorialService, shortTestService: ShortTestService, gradingService: GradingService, repository: EntityRepository<ScheincriteriaEntity>, em: EntityManager)
|
|||||||||||||||||||||||||||
Parameters :
|
Private calculateResultOfMultipleStudents | ||||||||
calculateResultOfMultipleStudents(params: MultipleStudentsCalculationParams)
|
||||||||
Calculates the results of all given criterias for all given students.
Parameters :
Returns :
ScheincriteriaSummaryByStudents
Criteria results for all given students of all given criterias. |
Private calculateResultOfSingleStudent | ||||||||
calculateResultOfSingleStudent(params: SingleStudentCalculationParams)
|
||||||||
Calculates the result of all given criterias for the given student and returns the result.
Parameters :
Returns :
ScheincriteriaSummary
Calculation result of all given criterias for the given student. |
Async create | ||||||||
create(dto: ScheinCriteriaDTO)
|
||||||||
Creates a new scheincriteria from the given DTO and returns the created one.
Parameters :
Returns :
Promise<IScheinCriteria>
The created scheincriteria |
Async delete | ||||||||
delete(id: string)
|
||||||||
Deletes the scheincriteria with the given ID if there is one.
Parameters :
Returns :
Promise<void>
Deleted ScheincriteriaDocument. |
Async findAll |
findAll()
|
Returns :
Promise<ScheincriteriaEntity[]>
All scheincriterias saved in the database. |
Async findById | ||||||||
findById(id: string)
|
||||||||
Searches for and returns the scheincriteria with the given ID.
Parameters :
Returns :
Promise<ScheincriteriaEntity>
ScheincriteriaDocument with the given ID. |
Async getFormData |
getFormData()
|
Returns :
Promise<FormDataResponse>
The form data parsed from the loaded scheincriteria blueprints. |
Async getInfoAboutCriteria | ||||||||
getInfoAboutCriteria(criteriaId: string)
|
||||||||
Collects and returns the information about the criteria with the given ID. The result will be returned.
Parameters :
Returns :
Promise<CriteriaInformation>
Information about the given criteria. |
Private Async getRequiredEntities | ||||||||||
getRequiredEntities(params: GetRequiredDocsParams)
|
||||||||||
Fetches all the required documents from the database. Some scenarios depend on the given
See ScheincriteriaService#getStudentEntities
Parameters :
Object containing the documents according to the given |
Async getResultOfStudent | ||||||||
getResultOfStudent(studentId: string)
|
||||||||
Calculates the results of all criterias for the given student and returns the result.
Parameters :
Returns :
Promise<ScheincriteriaSummary>
ScheinCriteriaSummary containing the result of the given student. |
Async getResultsOfAllStudents |
getResultsOfAllStudents()
|
Calculates the result of all criterias for all students and returns the result.
Returns :
Promise<ScheincriteriaSummaryByStudents>
Results of all criterias for all students. |
Async getResultsOfTutorial | ||||||||
getResultsOfTutorial(tutorialId: string)
|
||||||||
Calculates the results of all criterias for all students of the given tutorial. These results are then returned.
Parameters :
Returns :
Promise<ScheincriteriaSummaryByStudents>
Criteria results of all students of the given tutorial. |
Private Async getStudentEntities | ||||||||
getStudentEntities(params: Pick<GetRequiredDocsParams | "studentId" | "tutorialId">)
|
||||||||
Fetches StudentDocuments from the DB according to the
Parameters :
Returns :
Promise<StudentAndGradings[]>
StudentDocuments according to the given params. |
Async update | ||||||||||||
update(id: string, dto: ScheinCriteriaDTO)
|
||||||||||||
Updates the scheincriteria with the given ID and returns the updated version.
Parameters :
Returns :
Promise<IScheinCriteria>
Updated version of the scheincriteria. |
import { EntityRepository } from '@mikro-orm/core';
import { EntityManager } from '@mikro-orm/mysql';
import { InjectRepository } from '@mikro-orm/nestjs';
import { Inject, Injectable, NotFoundException } from '@nestjs/common';
import { FormDataResponse } from 'shared/model/FormTypes';
import {
CriteriaInformation,
IScheinCriteria,
ScheinCriteriaSummary as ScheincriteriaSummary,
ScheincriteriaSummaryByStudents,
SingleScheincriteriaSummaryByStudents,
} from 'shared/model/ScheinCriteria';
import { StudentStatus } from 'shared/model/Student';
import { ScheincriteriaEntity } from '../../database/entities/scheincriteria.entity';
import { Scheinexam } from '../../database/entities/scheinexam.entity';
import { Sheet } from '../../database/entities/sheet.entity';
import { ShortTest } from '../../database/entities/shorttest.entity';
import { Student } from '../../database/entities/student.entity';
import { CRUDService } from '../../helpers/CRUDService';
import { ScheinexamService } from '../scheinexam/scheinexam.service';
import { SheetService } from '../sheet/sheet.service';
import { ShortTestService } from '../short-test/short-test.service';
import { GradingService, StudentAndGradings } from '../student/grading.service';
import { StudentService } from '../student/student.service';
import { TutorialService } from '../tutorial/tutorial.service';
import { Scheincriteria } from './container/Scheincriteria';
import { ScheincriteriaContainer } from './container/scheincriteria.container';
import { ScheinCriteriaDTO } from './scheincriteria.dto';
interface CalculationParams {
criterias: ScheincriteriaEntity[];
exams: Scheinexam[];
sheets: Sheet[];
shortTests: ShortTest[];
}
interface SingleStudentCalculationParams extends CalculationParams {
studentInfo: StudentAndGradings;
}
interface MultipleStudentsCalculationParams extends CalculationParams {
studentInfos: StudentAndGradings[];
}
interface GetRequiredDocsParams {
criteriaId?: string;
studentId?: string;
tutorialId?: string;
}
@Injectable()
export class ScheincriteriaService
implements CRUDService<IScheinCriteria, ScheinCriteriaDTO, ScheincriteriaEntity>
{
constructor(
private readonly studentService: StudentService,
private readonly sheetService: SheetService,
private readonly scheinexamService: ScheinexamService,
private readonly tutorialService: TutorialService,
private readonly shortTestService: ShortTestService,
private readonly gradingService: GradingService,
@InjectRepository(ScheincriteriaEntity)
private readonly repository: EntityRepository<ScheincriteriaEntity>,
@Inject(EntityManager)
private readonly em: EntityManager
) {}
/**
* @returns All scheincriterias saved in the database.
*/
async findAll(): Promise<ScheincriteriaEntity[]> {
return this.repository.findAll();
}
/**
* Searches for and returns the scheincriteria with the given ID.
*
* @param id ID to search for.
*
* @returns ScheincriteriaDocument with the given ID.
*
* @throws `NotFoundException` - If no scheincriteria could be found with the given ID.
*/
async findById(id: string): Promise<ScheincriteriaEntity> {
const criteria = await this.repository.findOne({
id,
});
if (!criteria) {
throw new NotFoundException(`No scheincriteria with the ID '${id}' could be found.`);
}
return criteria;
}
/**
* Creates a new scheincriteria from the given DTO and returns the created one.
*
* @param dto DTO to create a criteria from.
*
* @returns The created scheincriteria
*
* @throws `NotFoundException` - If no scheincriteria could be generated with the provided identifier in the DTO.
* @throws `BadRequestException` - If the provided data is not a valid criteria.
*/
async create(dto: ScheinCriteriaDTO): Promise<IScheinCriteria> {
const scheincriteria = Scheincriteria.fromDTO(dto);
const entity = new ScheincriteriaEntity({
name: dto.name,
criteria: scheincriteria,
});
await this.em.persistAndFlush(entity);
return entity.toDTO();
}
/**
* Updates the scheincriteria with the given ID and returns the updated version.
*
* @param id ID of the scheincriteria to update.
* @param dto Data to update the scheincriteria with.
*
* @returns Updated version of the scheincriteria.
*
* @throws `NotFoundException` - If there is no scheincriteria saved with the given ID or if no scheincriteria could be generated from the given DTO.
* @throws `BadRequestException` - If the provided data is not a valid criteria.
*/
async update(id: string, dto: ScheinCriteriaDTO): Promise<IScheinCriteria> {
const scheincriteria = await this.findById(id);
scheincriteria.criteria = Scheincriteria.fromDTO(dto);
scheincriteria.name = dto.name;
await this.em.persistAndFlush(scheincriteria);
return scheincriteria.toDTO();
}
/**
* Deletes the scheincriteria with the given ID if there is one.
*
* @param id ID of the scheincriteria to delete.
*
* @returns Deleted ScheincriteriaDocument.
*
* @throws `NotFoundException` - If no scheincriteria with the given ID could be found.
*/
async delete(id: string): Promise<void> {
const criteria = await this.findById(id);
await this.em.removeAndFlush(criteria);
}
/**
* Collects and returns the information about the criteria with the given ID. The result will be returned.
*
* @param criteriaId ID of the criteria to get the information for.
*
* @returns Information about the given criteria.
*
* @throws `NotFoundException` - If no criteria with the given ID could be found.
*/
async getInfoAboutCriteria(criteriaId: string): Promise<CriteriaInformation> {
const { criterias, studentInfos, ...handIns } = await this.getRequiredEntities({
criteriaId,
});
const criteriaEntity = criterias[0];
const criteria: Scheincriteria = Scheincriteria.fromDTO(criteriaEntity.toDTO());
const [criteriaInfo, summaries] = await Promise.all([
criteria.getInformation({ ...handIns, students: studentInfos.map((s) => s.student) }),
this.calculateResultOfMultipleStudents({
criterias,
studentInfos,
...handIns,
}),
]);
const studentSummaries: SingleScheincriteriaSummaryByStudents = {};
Object.entries(summaries).forEach(([key, summary]) => {
studentSummaries[key] = summary.scheinCriteriaSummary[criteriaEntity.id];
});
return {
name: criteriaEntity.name,
studentSummaries,
...criteriaInfo,
};
}
/**
* Calculates the results of all criterias for the given student and returns the result.
*
* @param studentId Student ID to get the result for.
*
* @returns ScheinCriteriaSummary containing the result of the given student.
*
* @throws `NotFoundException` - If no student with the given ID could be found.
*/
async getResultOfStudent(studentId: string): Promise<ScheincriteriaSummary> {
const { studentInfos, ...params } = await this.getRequiredEntities({
studentId,
});
return this.calculateResultOfSingleStudent({
...params,
studentInfo: studentInfos[0],
});
}
/**
* Calculates the result of all criterias for all students and returns the result.
*
* @returns Results of all criterias for all students.
*/
async getResultsOfAllStudents(): Promise<ScheincriteriaSummaryByStudents> {
return this.calculateResultOfMultipleStudents(await this.getRequiredEntities());
}
/**
* Calculates the results of all criterias for all students of the given tutorial. These results are then returned.
*
* @param tutorialId ID of the tutorial.
*
* @returns Criteria results of all students of the given tutorial.
*
* @throws `NotFoundException` - If no tutorial with the given ID could be found.
*/
async getResultsOfTutorial(tutorialId: string): Promise<ScheincriteriaSummaryByStudents> {
return this.calculateResultOfMultipleStudents(
await this.getRequiredEntities({ tutorialId })
);
}
/**
* @returns The form data parsed from the loaded scheincriteria blueprints.
*/
async getFormData(): Promise<FormDataResponse> {
return ScheincriteriaContainer.getContainer().getFormData();
}
/**
* Calculates the result of all given criterias for the given student and returns the result.
*
* @param params Must contain the student, the criterias, sheets and exams.
*
* @returns Calculation result of all given criterias for the given student.
*/
private calculateResultOfSingleStudent(
params: SingleStudentCalculationParams
): ScheincriteriaSummary {
const summaries: ScheincriteriaSummary['scheinCriteriaSummary'] = {};
let passed = true;
for (const { id, name, criteria } of params.criterias) {
const result = criteria.checkCriteriaStatus({
student: params.studentInfo.student,
gradingsOfStudent: params.studentInfo.gradingsOfStudent,
sheets: params.sheets,
exams: params.exams,
shortTests: params.shortTests,
});
summaries[id] = { id, name, ...result };
passed = passed && result.passed;
}
return {
student: params.studentInfo.student.toDTO(),
passed:
passed || params.studentInfo.student.status === StudentStatus.NO_SCHEIN_REQUIRED,
scheinCriteriaSummary: summaries,
};
}
/**
* Calculates the results of all given criterias for all given students.
*
* @param params Must contain a list of students, criterias, sheets and exams.
*
* @returns Criteria results for all given students of all given criterias.
*/
private calculateResultOfMultipleStudents(
params: MultipleStudentsCalculationParams
): ScheincriteriaSummaryByStudents {
const { studentInfos, ...infos } = params;
const summaries: ScheincriteriaSummaryByStudents = {};
studentInfos.forEach((info) => {
summaries[info.student.id] = this.calculateResultOfSingleStudent({
...infos,
studentInfo: info,
});
});
return summaries;
}
/**
* Fetches all the required documents from the database.
*
* Some scenarios depend on the given `params`:
* - `criteriaId` - If provided the `criterias` array will only contain the criteria with the ID. Otherwise the array will contain all criterias saved in the DB.
* - `tutorialId` - If provided the `students` array will only contain those students from the tutorial with the given ID. Otherwise the description of `studentId` will apply. __Please note__: In case both `tutorialId` and `studentId` are provided `tutorialId` is taken and `studentId` is ignored.
* - `studentId` - If provided the `students` array will only contain the student with the ID. Otherwise the array will contain all students saved in the DB (except `tutorialId` is provided).
*
* @param params Parameters which determine what gets actually fetched in certain scenarios (see above).
*
* @returns Object containing the documents according to the given `params`.
* @throws `NotFoundException` - If any of the `params` is set and the corresponding document can not be found.
*
* @see ScheincriteriaService#getStudentEntities
*/
private async getRequiredEntities(
params: GetRequiredDocsParams = {}
): Promise<MultipleStudentsCalculationParams> {
const { criteriaId, studentId, tutorialId } = params;
const [criterias, studentInfos, sheets, exams, shortTests] = await Promise.all([
criteriaId ? [await this.findById(criteriaId)] : this.findAll(),
this.getStudentEntities({ studentId, tutorialId }),
this.sheetService.findAll(),
this.scheinexamService.findAll(),
this.shortTestService.findAll(),
]);
return { criterias, studentInfos, sheets, exams, shortTests };
}
/**
* Fetches StudentDocuments from the DB according to the `params` object:
*
* - `tutorialId` - If provided the `students` array will only contain those students from the tutorial with the given ID. Otherwise the description of `studentId` will apply. __Please note__: In case both `tutorialId` and `studentId` are provided `tutorialId` is taken and `studentId` is ignored.
* - `studentId` - If provided the `students` array will only contain the student with the ID. Otherwise the array will contain all students saved in the DB (except `tutorialId` is provided).
*
* @param params Params determining what documents are fetched (see above).
*
* @returns StudentDocuments according to the given params.
* @throws `NotFoundException` - If any of the `params` is set and the corresponding document can not be found.
*/
private async getStudentEntities(
params: Pick<GetRequiredDocsParams, 'studentId' | 'tutorialId'>
): Promise<StudentAndGradings[]> {
const { studentId, tutorialId } = params;
let students: Student[];
if (tutorialId) {
students = await this.tutorialService.getAllStudentsOfTutorial(tutorialId);
} else if (studentId) {
students = [await this.studentService.findById(studentId)];
} else {
students = await this.studentService.findAll();
}
return this.gradingService.findAllGradingsOfMultipleStudents(students);
}
}