import { SafePromise, Exception } from "@rolesvillesoftware/tools/dist"; import { Calculator } from "./Calculator"; import { ExamFact, ExamQuestionFact, QuestionFact, QuestionStat, ExamStat } from "../models"; import { Logger } from "../Logger"; export class QuestionCalculator extends Calculator<{examStat: ExamStat; question: ExamQuestionFact}, QuestionStat> { private async getQuestionStat(examQuestion: ExamQuestionFact): Promise { const query = this.processResults(await SafePromise.run(() => this.context.questionStat.selectOrCreate((i, b) => i.examQuestionFactId === b.examQuestionFactId, { examQuestionFactId: examQuestion.id } as QuestionStat) )); if (query.count === 0) { throw new Exception("Unable to create Question State record"); } return query.toArray()[0]; } private async getQuestionFacts(examQuestion: ExamQuestionFact): Promise { const query = this.processResults(await SafePromise.run(() => this.context.questionFact .where((i, b) => i.questionDimId === b.questionDimId && i.examDimId === b.examDimId, examQuestion) .execute() .toPromise() )); return query.toArray(); } async calculate(input?: {examStat: ExamStat; question: ExamQuestionFact}): Promise { if (input == null) { return null; } Logger.log(`\t\tLoading question facts`); const facts = this.processResults(await SafePromise.run(() => this.getQuestionFacts(input.question))); if (!facts.every((v, i) => i === 0 || v.questionDimId === facts[i - 1].questionDimId)) { throw new Exception("Not all question facts are for the same question."); } if (facts.length !== input.examStat.students.length) { throw new Exception("Exam to Question student count mis-match"); } Logger.log(`\t\tRetrieving or creating question stats record`); const stat = this.processResults(await SafePromise.run(() => this.getQuestionStat(input.question))); Logger.log(`\t\tCalculating question statistics`); stat.populate(facts, input.examStat); Logger.log(`\tQuestion statistics completed`); return stat; } }