api/lib/domain/services/assessment-result-service.js
const moment = require('moment');
const AssessmentResult = require('../../domain/models/AssessmentResult');
const skillService = require('../../domain/services/skills-service');
const assessmentService = require('../../domain/services/assessment-service');
const assessmentRepository = require('../../infrastructure/repositories/assessment-repository');
const assessmentResultRepository = require('../../infrastructure/repositories/assessment-result-repository');
const competenceMarkRepository = require('../../infrastructure/repositories/competence-mark-repository');
const certificationCourseRepository = require('../../infrastructure/repositories/certification-course-repository');
const { NotFoundError, AlreadyRatedAssessmentError } = require('../../domain/errors');
// TODO: Should compute pixScore automatically in AssessmentResult + create an Utils to compute level/status everywhere
function _getAssessmentResultEvaluations(marks, assessmentType) {
const pixScore = marks.reduce((totalPixScore, mark) => {
return totalPixScore + mark.score;
}, 0);
let level = Math.floor(pixScore / 8);
let status = 'validated';
if(pixScore === 0 && assessmentType === 'CERTIFICATION') {
status = 'rejected';
level = -1;
}
return { pixScore, level, status };
}
function _validatedDataForAllCompetenceMark(marks) {
return Promise.all(marks.map((mark) => mark.validate()));
}
function evaluateFromAssessmentId(assessmentId) {
let assessment;
return assessmentRepository.get(assessmentId)
.then((foundAssessment) => {
assessment = foundAssessment;
if (!assessment) {
throw new NotFoundError();
}
if (assessment.isCompleted()) {
throw new AlreadyRatedAssessmentError();
}
return Promise.all([
assessmentService.getSkills(assessment),
assessmentService.getCompetenceMarks(assessment)
]).then(([skills, marks]) => {
const { pixScore, level, status } = _getAssessmentResultEvaluations(marks, assessment.type);
const assessmentResult = new AssessmentResult({
emitter: 'PIX-ALGO',
commentForJury: 'Computed',
level: level,
pixScore: pixScore,
status,
assessmentId
});
assessment.setCompleted();
return Promise.all([
assessmentResultRepository.save(assessmentResult),
marks,
skillService.saveAssessmentSkills(skills),
assessmentRepository.save(assessment),
]);
}).then(([assessmentResult, marks]) => {
const assessmentResultId = assessmentResult.id;
marks = marks.map((mark) => {
mark.assessmentResultId = assessmentResultId;
return mark;
});
return Promise.all(marks.map((mark) => competenceMarkRepository.save(mark)));
}).then(() => {
if (assessmentService.isCertificationAssessment(assessment)) {
return certificationCourseRepository.changeCompletionDate(assessment.courseId,
moment().toISOString());
}
});
});
}
function save(assessmentResult, competenceMarks) {
return _validatedDataForAllCompetenceMark(competenceMarks)
.then(() => assessmentResultRepository.save(assessmentResult))
.then((assessmentResult) => {
const competenceMarksSaved = competenceMarks.map((competenceMark) => {
competenceMark.assessmentResultId = assessmentResult.id;
return competenceMarkRepository.save(competenceMark);
});
return Promise.all(competenceMarksSaved);
});
}
module.exports = {
save,
evaluateFromAssessmentId
};