Skip to content

Commit

Permalink
[BUGFIX] Utiliser la date de réconciliation du candidat lors du scori…
Browse files Browse the repository at this point in the history
…ng de la certification en V2 (PIX-15138).

 #10572
  • Loading branch information
pix-service-auto-merge authored Nov 20, 2024
2 parents 1483d19 + f5a4029 commit 5ddd957
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
* @typedef {import('../index.js').AssessmentResultRepository} AssessmentResultRepository
* @typedef {import('../index.js').CertificationCourseRepository} CertificationCourseRepository
* @typedef {import('../index.js').CompetenceMarkRepository} CompetenceMarkRepository
* @typedef {import('../index.js').CertificationCandidateRepository} CertificationCandidateRepository
* @typedef {import('../index.js').ScoringDegradationService} ScoringDegradationService
* @typedef {import('../index.js').ScoringCertificationService} ScoringCertificationService
* @typedef {import('../index.js').ScoringService} ScoringService
* @typedef {import('../index.js').PlacementProfileService} PlacementProfileService
* @typedef {import('../../../../session-management/domain/models/CertificationAssessment.js').CertificationAssessment} CertificationAssessment
*/

import _ from 'lodash';
Expand All @@ -24,13 +27,19 @@ import { AlgorithmEngineVersion } from '../../../../shared/domain/models/Algorit

/**
* @param {Object} params
* @param {{juryId: number}} params.[event]
* @param {'PIX-ALGO'|'Jury Pix'|'PIX-ALGO-FRAUD-REJECTION'} params.emitter
* @param {CertificationAssessment} params.certificationAssessment
* @param {AssessmentResultRepository} params.assessmentResultRepository
* @param {CertificationCourseRepository} params.certificationCourseRepository
* @param {CompetenceMarkRepository} params.competenceMarkRepository
* @param {ScoringCertificationService} params.scoringCertificationService
* @param {AreaRepository} params.areaRepository
* @param {PlacementProfileService} params.placementProfileService
* @param {ScoringService} params.scoringService
* @param {CertificationCandidateRepository} params.certificationCandidateRepository
* @param {Object} params.dependencies
* @param {calculateCertificationAssessmentScore} params.dependencies.calculateCertificationAssessmentScore
*/
export const handleV2CertificationScoring = async ({
event,
Expand All @@ -43,14 +52,15 @@ export const handleV2CertificationScoring = async ({
areaRepository,
placementProfileService,
scoringService,
certificationCandidateRepository,
dependencies = { calculateCertificationAssessmentScore },
}) => {
const certificationAssessmentScore = await dependencies.calculateCertificationAssessmentScore({
certificationAssessment,
continueOnError: false,
areaRepository,
placementProfileService,
scoringService,
certificationCandidateRepository,
});
const certificationCourse = await certificationCourseRepository.get({
id: certificationAssessment.certificationCourseId,
Expand Down Expand Up @@ -78,18 +88,24 @@ export const handleV2CertificationScoring = async ({

/**
* @param {Object} params
* @param {ScoringService} params.dependencies.scoringService
* @param {CertificationAssessment} params.certificationAssessment
* @param {ScoringService} params.scoringService
* @param {CertificationCandidateRepository} params.certificationCandidateRepository
*/
export const calculateCertificationAssessmentScore = async function ({
certificationAssessment,
continueOnError,
areaRepository,
placementProfileService,
scoringService,
certificationCandidateRepository,
}) {
const candidate = await certificationCandidateRepository.findByAssessmentId({
assessmentId: certificationAssessment.id,
});

const testedCompetences = await _getTestedCompetences({
userId: certificationAssessment.userId,
limitDate: certificationAssessment.createdAt,
limitDate: candidate.reconciledAt,
version: AlgorithmEngineVersion.V2,
placementProfileService,
});
Expand All @@ -105,16 +121,13 @@ export const calculateCertificationAssessmentScore = async function ({
);

const allAreas = await areaRepository.list();
return _getResult(
matchingAnswers,
matchingCertificationChallenges,
testedCompetences,
allAreas,
continueOnError,
scoringService,
);
return _getResult(matchingAnswers, matchingCertificationChallenges, testedCompetences, allAreas, scoringService);
};

/**
* @param {Object} params
* @param {PlacementProfileService} params.placementProfileService
*/
async function _getTestedCompetences({ userId, limitDate, version, placementProfileService }) {
const placementProfile = await placementProfileService.getPlacementProfile({ userId, limitDate, version });
return _(placementProfile.userCompetences)
Expand Down Expand Up @@ -143,7 +156,6 @@ function _getCompetenceMarksWithCertifiedLevelAndScore(
listCompetences,
reproducibilityRate,
certificationChallenges,
continueOnError,
answerCollection,
allAreas,
scoringService,
Expand All @@ -152,11 +164,9 @@ function _getCompetenceMarksWithCertifiedLevelAndScore(
const challengesForCompetence = _.filter(certificationChallenges, { competenceId: competence.id });
const answersForCompetence = _selectAnswersMatchingCertificationChallenges(answers, challengesForCompetence);

if (!continueOnError) {
CertificationContract.assertThatCompetenceHasAtLeastOneChallenge(challengesForCompetence, competence.index);
CertificationContract.assertThatEveryAnswerHasMatchingChallenge(answersForCompetence, challengesForCompetence);
CertificationContract.assertThatNoChallengeHasMoreThanOneAnswer(answersForCompetence, challengesForCompetence);
}
CertificationContract.assertThatCompetenceHasAtLeastOneChallenge(challengesForCompetence, competence.index);
CertificationContract.assertThatEveryAnswerHasMatchingChallenge(answersForCompetence, challengesForCompetence);
CertificationContract.assertThatNoChallengeHasMoreThanOneAnswer(answersForCompetence, challengesForCompetence);

const certifiedLevel = CertifiedLevel.from({
numberOfChallenges: answerCollection.numberOfChallengesForCompetence(competence.id),
Expand Down Expand Up @@ -196,10 +206,8 @@ function _getCompetenceMarksWithFailedLevel(listCompetences, allAreas, scoringSe
/**
* @param {ScoringService} scoringService
*/
function _getResult(answers, certificationChallenges, testedCompetences, allAreas, continueOnError, scoringService) {
if (!continueOnError) {
CertificationContract.assertThatWeHaveEnoughAnswers(answers, certificationChallenges);
}
function _getResult(answers, certificationChallenges, testedCompetences, allAreas, scoringService) {
CertificationContract.assertThatWeHaveEnoughAnswers(answers, certificationChallenges);

const answerCollection = AnswerCollectionForScoring.from({ answers, challenges: certificationChallenges });

Expand Down Expand Up @@ -227,16 +235,13 @@ function _getResult(answers, certificationChallenges, testedCompetences, allArea
testedCompetences,
reproducibilityRate.value,
certificationChallenges,
continueOnError,
answerCollection,
allAreas,
scoringService,
);
const scoreAfterRating = _getSumScoreFromCertifiedCompetences(competenceMarks);

if (!continueOnError) {
CertificationContract.assertThatScoreIsCoherentWithReproducibilityRate(scoreAfterRating, reproducibilityRate.value);
}
CertificationContract.assertThatScoreIsCoherentWithReproducibilityRate(scoreAfterRating, reproducibilityRate.value);

return new CertificationAssessmentScore({
competenceMarks,
Expand All @@ -247,6 +252,7 @@ function _getResult(answers, certificationChallenges, testedCompetences, allArea

/**
* @param {Object} params
* @param {CertificationAssessment} params.certificationAssessment
* @param {ScoringCertificationService} params.scoringCertificationService
*/
function _createV2AssessmentResult({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* @typedef {import('../../../../shared/domain/models/CertificationChallengeWithType.js').CertificationChallengeWithType} CertificationChallengeWithType
* @typedef {import('../../../../evaluation/domain/models/Answer.js').Answer} Answer
*/
import JoiDate from '@joi/date';
import BaseJoi from 'joi';
const Joi = BaseJoi.extend(JoiDate);
Expand Down Expand Up @@ -36,6 +40,12 @@ const certificationAssessmentSchema = Joi.object({
});

class CertificationAssessment {
/**
* @param {Object} params
* @param {Date} params.createdAt certification course creation date
* @param {Array<CertificationChallengeWithType>} params.certificationChallenges
* @param {Array<Answer>} params.certificationAnswersByDate
*/
constructor({
id,
userId,
Expand Down
9 changes: 9 additions & 0 deletions api/src/shared/domain/models/PlacementProfile.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
/**
* @typedef {import('./UserCompetence.js').UserCompetence} UserCompetence
*/
import _ from 'lodash';

import { MINIMUM_CERTIFIABLE_COMPETENCES_FOR_CERTIFIABILITY } from '../constants.js';

class PlacementProfile {
/**
* @param {Object} params
* @param {Date} params.profileDate
* @param {number} params.userId
* @param {Array<UserCompetence>} params.userCompetences
*/
constructor({ profileDate, userId, userCompetences } = {}) {
this.profileDate = profileDate;
this.userId = userId;
Expand Down
Loading

0 comments on commit 5ddd957

Please sign in to comment.