Skip to content

Commit

Permalink
[TECH] CampaignLearningContent hérite de LearningContent (PIX-16195)
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Jan 29, 2025
2 parents 4899b0f + 5fa42d0 commit 119cddc
Show file tree
Hide file tree
Showing 20 changed files with 189 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import _ from 'lodash';
import { knex } from '../../../db/knex-database-connection.js';
import * as campaignRepository from '../../../src/prescription/campaign/infrastructure/repositories/campaign-repository.js';
import { NoSkillsInCampaignError, NotFoundError } from '../../../src/shared/domain/errors.js';
import { CampaignLearningContent } from '../../../src/shared/domain/models/CampaignLearningContent.js';
import { LearningContent } from '../../../src/shared/domain/models/LearningContent.js';
import * as areaRepository from '../../../src/shared/infrastructure/repositories/area-repository.js';
import * as competenceRepository from '../../../src/shared/infrastructure/repositories/competence-repository.js';
Expand All @@ -17,7 +18,7 @@ async function findByCampaignId(campaignId, locale) {

const frameworks = await _getLearningContentBySkillIds(skills, locale);

return new LearningContent(frameworks);
return new CampaignLearningContent(frameworks);
}

async function findByTargetProfileId(targetProfileId, locale) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { UserNotAuthorizedToAccessEntityError } from '../../../../shared/domain/errors.js';
import { CampaignLearningContent } from '../../../../shared/domain/models/CampaignLearningContent.js';
import { CampaignParticipationDeletedError } from '../errors.js';

const computeCampaignParticipationAnalysis = async function ({
Expand Down Expand Up @@ -28,8 +27,7 @@ const computeCampaignParticipationAnalysis = async function ({
return null;
}

const learningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const campaignLearningContent = new CampaignLearningContent(learningContent);
const campaignLearningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const tutorials = await tutorialRepository.list({ locale });

return campaignAnalysisRepository.getCampaignParticipationAnalysis(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { knex } from '../../../../../db/knex-database-connection.js';
import * as learningContentRepository from '../../../../../lib/infrastructure/repositories/learning-content-repository.js';
import { NotFoundError } from '../../../../shared/domain/errors.js';
import { CampaignLearningContent } from '../../../../shared/domain/models/CampaignLearningContent.js';
import * as knowledgeElementRepository from '../../../../shared/infrastructure/repositories/knowledge-element-repository.js';
import { CampaignAssessmentParticipationResult } from '../../domain/models/CampaignAssessmentParticipationResult.js';

const getByCampaignIdAndCampaignParticipationId = async function ({ campaignId, campaignParticipationId, locale }) {
const learningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const campaignLearningContent = new CampaignLearningContent(learningContent);
const campaignLearningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const result = await _fetchCampaignAssessmentParticipationResultAttributesFromCampaignParticipation(
campaignId,
campaignParticipationId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { UserNotAuthorizedToAccessEntityError } from '../../../../shared/domain/errors.js';
import { CampaignLearningContent } from '../../../../shared/domain/models/CampaignLearningContent.js';

const computeCampaignAnalysis = async function ({
userId,
Expand All @@ -16,8 +15,7 @@ const computeCampaignAnalysis = async function ({
throw new UserNotAuthorizedToAccessEntityError('User does not have access to this campaign');
}

const learningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const campaignLearningContent = new CampaignLearningContent(learningContent);
const campaignLearningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const tutorials = await tutorialRepository.list({ locale });

return campaignAnalysisRepository.getCampaignAnalysis(campaignId, campaignLearningContent, tutorials);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { UserNotAuthorizedToAccessEntityError } from '../../../../shared/domain/errors.js';
import { CampaignLearningContent } from '../../../../shared/domain/models/CampaignLearningContent.js';

const computeCampaignCollectiveResult = async function ({
userId,
Expand All @@ -15,8 +14,7 @@ const computeCampaignCollectiveResult = async function ({
throw new UserNotAuthorizedToAccessEntityError('User does not have access to this campaign');
}

const learningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
const campaignLearningContent = new CampaignLearningContent(learningContent);
const campaignLearningContent = await learningContentRepository.findByCampaignId(campaignId, locale);
return campaignCollectiveResultRepository.getCampaignCollectiveResult(campaignId, campaignLearningContent);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ dayjs.extend(utc);
dayjs.extend(timezone);

import { CampaignTypeError } from '../../../../shared/domain/errors.js';
import { CampaignLearningContent } from '../../../../shared/domain/models/index.js';
import { CampaignAssessmentExport } from '../../infrastructure/serializers/csv/campaign-assessment-export.js';

/**
Expand Down Expand Up @@ -64,7 +63,6 @@ const startWritingCampaignAssessmentResultsToStream = async function ({
const targetProfile = await targetProfileRepository.getByCampaignId(campaign.id);
const learningContent = await learningContentRepository.findByCampaignId(campaign.id, i18n.getLocale());
const stageCollection = await stageCollectionRepository.findStageCollection({ campaignId });
const campaignLearningContent = new CampaignLearningContent(learningContent);

const organization = await organizationRepository.get(campaign.organizationId);
const campaignParticipationInfos = await campaignParticipationInfoRepository.findByCampaignId(campaign.id);
Expand All @@ -79,7 +77,7 @@ const startWritingCampaignAssessmentResultsToStream = async function ({
outputStream: writableStream,
organization,
targetProfile,
learningContent: campaignLearningContent,
learningContent,
stageCollection,
campaign,
translate,
Expand Down
122 changes: 7 additions & 115 deletions api/src/shared/domain/models/CampaignLearningContent.js
Original file line number Diff line number Diff line change
@@ -1,124 +1,16 @@
import _ from 'lodash';
import { LearningContent } from './LearningContent.js';

class CampaignLearningContent {
constructor(learningContent) {
this._learningContent = learningContent;
}

get skills() {
return this._learningContent.skills;
}

get tubes() {
return this._learningContent.tubes;
}

get competences() {
return this._learningContent.competences.sort((a, b) => a.index.localeCompare(b.index));
class CampaignLearningContent extends LearningContent {
constructor(frameworks) {
super(frameworks);
}

get areas() {
return this._learningContent.areas.sort((a, b) => a.code.localeCompare(b.code));
}

findSkill(skillId) {
return this._learningContent.findSkill(skillId);
}

findTube(tubeId) {
return this._learningContent.findTube(tubeId);
}

findCompetence(competenceId) {
return this._learningContent.findCompetence(competenceId);
}

findArea(areaId) {
return this._learningContent.findArea(areaId);
}

get maxSkillDifficulty() {
const skillMaxDifficulty = _.maxBy(this.skills, 'difficulty');
return skillMaxDifficulty ? skillMaxDifficulty.difficulty : null;
}

get tubeIds() {
return this.tubes.map((tube) => tube.id);
}

/** @deprecated use findCompetence */
getCompetence(competenceId) {
return this.findCompetence(competenceId);
return super.areas.sort((a, b) => a.code.localeCompare(b.code));
}

getValidatedKnowledgeElementsGroupedByTube(knowledgeElements) {
return this._filterTargetedKnowledgeElementAndGroupByTube(
knowledgeElements,
(knowledgeElement) => knowledgeElement.isValidated,
);
}

getKnowledgeElementsGroupedByCompetence(knowledgeElements) {
return this._filterTargetedKnowledgeElementAndGroupByCompetence(knowledgeElements);
}

countValidatedTargetedKnowledgeElementsByCompetence(knowledgeElements) {
const validatedGroupedByCompetence = this._filterTargetedKnowledgeElementAndGroupByCompetence(
knowledgeElements,
(knowledgeElement) => knowledgeElement.isValidated,
);
return _.mapValues(validatedGroupedByCompetence, 'length');
}

get skillNames() {
return this.skills.map((skill) => skill.name);
}

_getTubeIdOfSkill(skillId) {
const skillTube = this.tubes.find((tube) => tube.hasSkill(skillId));

return skillTube ? skillTube.id : null;
}

_filterTargetedKnowledgeElementAndGroupByTube(knowledgeElements, knowledgeElementFilter = () => true) {
const knowledgeElementsGroupedByTube = {};
for (const tubeId of this.tubeIds) {
knowledgeElementsGroupedByTube[tubeId] = [];
}
for (const knowledgeElement of knowledgeElements) {
const tubeId = this._getTubeIdOfSkill(knowledgeElement.skillId);
if (tubeId && knowledgeElementFilter(knowledgeElement)) {
knowledgeElementsGroupedByTube[tubeId].push(knowledgeElement);
}
}

return knowledgeElementsGroupedByTube;
}

_filterTargetedKnowledgeElementAndGroupByCompetence(knowledgeElements, knowledgeElementFilter = () => true) {
const knowledgeElementsGroupedByCompetence = {};
for (const competence of this.competences) {
knowledgeElementsGroupedByCompetence[competence.id] = [];
}
for (const knowledgeElement of knowledgeElements) {
const competenceId = this.findCompetenceIdOfSkill(knowledgeElement.skillId);
if (competenceId && knowledgeElementFilter(knowledgeElement)) {
knowledgeElementsGroupedByCompetence[competenceId].push(knowledgeElement);
}
}

return knowledgeElementsGroupedByCompetence;
}

findCompetenceIdOfSkill(skillId) {
const tubeId = this.findSkill(skillId)?.tubeId;
if (!tubeId) return null;
return this.findTube(tubeId).competenceId;
}

findAreaOfCompetence(competence) {
const area = this.findArea(competence.areaId);
return area || null;
get competences() {
return super.competences.sort((a, b) => a.index.localeCompare(b.index));
}
}

Expand Down
74 changes: 74 additions & 0 deletions api/src/shared/domain/models/LearningContent.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import _ from 'lodash';

class LearningContent {
constructor(frameworks) {
this.frameworks = frameworks;
Expand All @@ -24,6 +26,14 @@ class LearningContent {
return this.tubes.flatMap((tube) => tube.skills);
}

get skillNames() {
return this.skills.map((skill) => skill.name);
}

get tubeIds() {
return this.tubes.map((tube) => tube.id);
}

findSkill(skillId) {
return this.skills.find((skill) => skill.id === skillId) ?? null;
}
Expand All @@ -40,6 +50,11 @@ class LearningContent {
return this.areas.find((area) => area.id === areaId) ?? null;
}

findAreaOfCompetence(competence) {
const area = this.findArea(competence.areaId);
return area || null;
}

findFramework(frameworkId) {
return this.frameworks.find((framework) => framework.id === frameworkId) ?? null;
}
Expand All @@ -55,6 +70,65 @@ class LearningContent {
if (!frameworkId) return '';
return this.findFramework(frameworkId).name;
}
getValidatedKnowledgeElementsGroupedByTube(knowledgeElements) {
return this._filterTargetedKnowledgeElementAndGroupByTube(
knowledgeElements,
(knowledgeElement) => knowledgeElement.isValidated,
);
}

getKnowledgeElementsGroupedByCompetence(knowledgeElements) {
return this._filterTargetedKnowledgeElementAndGroupByCompetence(knowledgeElements);
}

countValidatedTargetedKnowledgeElementsByCompetence(knowledgeElements) {
const validatedGroupedByCompetence = this._filterTargetedKnowledgeElementAndGroupByCompetence(
knowledgeElements,
(knowledgeElement) => knowledgeElement.isValidated,
);
return _.mapValues(validatedGroupedByCompetence, 'length');
}

_getTubeIdOfSkill(skillId) {
const skillTube = this.tubes.find((tube) => tube.hasSkill(skillId));

return skillTube ? skillTube.id : null;
}

_filterTargetedKnowledgeElementAndGroupByTube(knowledgeElements, knowledgeElementFilter = () => true) {
const knowledgeElementsGroupedByTube = {};
for (const tubeId of this.tubeIds) {
knowledgeElementsGroupedByTube[tubeId] = [];
}
for (const knowledgeElement of knowledgeElements) {
const tubeId = this._getTubeIdOfSkill(knowledgeElement.skillId);
if (tubeId && knowledgeElementFilter(knowledgeElement)) {
knowledgeElementsGroupedByTube[tubeId].push(knowledgeElement);
}
}

return knowledgeElementsGroupedByTube;
}

_filterTargetedKnowledgeElementAndGroupByCompetence(knowledgeElements, knowledgeElementFilter = () => true) {
const knowledgeElementsGroupedByCompetence = {};
for (const competence of this.competences) {
knowledgeElementsGroupedByCompetence[competence.id] = [];
}
for (const knowledgeElement of knowledgeElements) {
const competenceId = this.findCompetenceIdOfSkill(knowledgeElement.skillId);
if (competenceId && knowledgeElementFilter(knowledgeElement)) {
knowledgeElementsGroupedByCompetence[competenceId].push(knowledgeElement);
}
}

return knowledgeElementsGroupedByCompetence;
}

get maxSkillDifficulty() {
const skillMaxDifficulty = _.maxBy(this.skills, 'difficulty');
return skillMaxDifficulty ? skillMaxDifficulty.difficulty : null;
}
}

export { LearningContent };
Loading

0 comments on commit 119cddc

Please sign in to comment.