Skip to content

Commit

Permalink
[TECH] Regrouper les différents model de campagne dans l'API (PIX-15820)
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Jan 16, 2025
2 parents 01fe131 + 858e115 commit dee799e
Show file tree
Hide file tree
Showing 18 changed files with 72 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const sendCompletedParticipationResultsToPoleEmploi = async ({
const campaign = await campaignRepository.get(participation.campaignId);
const organization = await organizationRepository.get(campaign.organizationId);

if (campaign.isAssessment() && organization.isPoleEmploi) {
if (campaign.isAssessment && organization.isPoleEmploi) {
const user = await userRepository.get(participation.userId);
const targetProfile = await targetProfileRepository.get(campaign.targetProfileId);
const assessment = await assessmentRepository.get(participation.lastAssessment.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async function insertMissingPoleEmploiSendingFromDate(startDate, endDate = new D
const campaign = await campaignRepository.get(campaignByCode.id);
const organization = await organizationRepository.get(campaign.organizationId);

if (!campaign.isAssessment() || !organization.isPoleEmploi) {
if (!campaign.isAssessment || !organization.isPoleEmploi) {
throw new Error('La campagne ne respecte pas les conditions pour générer les événements');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ class CampaignParticipation {
throw new CampaignParticiationInvalidStatus(this.id, CampaignParticipationStatuses.TO_SHARE);
}

if (this.campaign.isProfilesCollection()) {
//TODO: rewrite when we have only one model for Campaign, for now now tests are based on Campaign.js from api context
if (this.campaign.type === 'PROFILES_COLLECTION') {
throw new CantImproveCampaignParticipationError();
}
}
Expand All @@ -115,7 +116,8 @@ class CampaignParticipation {
if (this.isDeleted) {
throw new CampaignParticipationDeletedError('Cannot share results on a deleted participation.');
}
if (this.campaign.isAssessment() && lastAssessmentNotCompleted(this)) {
//TODO: rewrite when we have only one model for Campaign, for now tests are based on Campaign.js from api context
if (this.campaign.type === 'ASSESSMENT' && lastAssessmentNotCompleted(this)) {
throw new AssessmentNotCompletedError();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const dependencies = {
badgeAcquisitionRepository,
badgeForCalculationRepository,
badgeRepository,
campaignRepository,
campaignAnalysisRepository,
campaignAssessmentParticipationRepository,
campaignAssessmentParticipationResultRepository,
Expand All @@ -99,7 +100,6 @@ const dependencies = {
campaignParticipationRepository,
campaignParticipationResultRepository,
campaignProfileRepository,
campaignRepository,
targetProfileRepository,
compareStagesAndAcquiredStages,
competenceEvaluationRepository,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const sendSharedParticipationResultsToPoleEmploi = async ({
const campaign = await campaignRepository.get(participation.campaignId);
const organization = await organizationRepository.get(campaign.organizationId);

if (campaign.isAssessment() && organization.isPoleEmploi) {
//TODO: rewrite when we have only one model for Campaign, for now tests are based on Campaign.js from api context
if (campaign.type === 'ASSESSMENT' && organization.isPoleEmploi) {
const badges = await badgeRepository.findByCampaignId(participation.campaignId);
const badgeAcquiredIds = await badgeAcquisitionRepository.getAcquiredBadgeIds({
badgeIds: badges.map((badge) => badge.id),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const sendStartedParticipationResultsToPoleEmploi = async ({
const campaign = await campaignRepository.get(participation.campaignId);
const organization = await organizationRepository.get(campaign.organizationId);

if (campaign.isAssessment() && organization.isPoleEmploi) {
if (campaign.isAssessment && organization.isPoleEmploi) {
const user = await userRepository.get(participation.userId);
const targetProfile = await targetProfileRepository.get(campaign.targetProfileId);
const payload = PoleEmploiPayload.buildForParticipationStarted({
Expand Down
9 changes: 6 additions & 3 deletions api/src/prescription/campaign/domain/models/Campaign.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,24 @@ class Campaign {
this.hasParticipation = participationCount > 0;
}

isAssessment() {
get isAssessment() {
return this.type === CampaignTypes.ASSESSMENT;
}

isProfilesCollection() {
get isProfilesCollection() {
return this.type === CampaignTypes.PROFILES_COLLECTION;
}

isArchived() {
get isArchived() {
return Boolean(this.archivedAt);
}

get isDeleted() {
return Boolean(this.deletedAt);
}
get isAccessible() {
return !this.archivedAt && !this.deletedAt;
}

delete(userId) {
if (this.deletedAt) {
Expand Down
54 changes: 6 additions & 48 deletions api/src/prescription/campaign/domain/models/CampaignManagement.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,30 @@
import { CampaignTypes } from '../../../shared/domain/constants.js';
class CampaignManagement {
import { Campaign } from './Campaign.js';

class CampaignManagement extends Campaign {
constructor({
id,
code,
name,
idPixLabel,
idPixType,
createdAt,
archivedAt,
deletedAt,
type,
creatorLastName,
creatorFirstName,
creatorId,
organizationId,
organizationName,
targetProfileId,
targetProfileName,
title,
customLandingPageText,
customResultPageText,
customResultPageButtonText,
customResultPageButtonUrl,
isForAbsoluteNovice,
ownerLastName,
ownerFirstName,
ownerId,
shared,
started,
completed,
multipleSendings,
...campaignAttributes
} = {}) {
this.id = id;
this.code = code;
this.name = name;
this.type = type;
this.idPixLabel = idPixLabel;
this.idPixType = idPixType;
this.createdAt = createdAt;
this.archivedAt = archivedAt;
this.deletedAt = deletedAt;
super(campaignAttributes);
this.creatorLastName = creatorLastName;
this.creatorFirstName = creatorFirstName;
this.creatorId = creatorId;
this.organizationId = organizationId;
this.organizationName = organizationName;
this.targetProfileId = targetProfileId;
this.targetProfileName = targetProfileName;
this.isForAbsoluteNovice = isForAbsoluteNovice;
this.title = title;
this.customLandingPageText = customLandingPageText;
this.customResultPageText = customResultPageText;
this.customResultPageButtonText = customResultPageButtonText;
this.customResultPageButtonUrl = customResultPageButtonUrl;
this.ownerLastName = ownerLastName;
this.ownerFirstName = ownerFirstName;
this.ownerId = ownerId;
this.sharedParticipationsCount = shared;
this.totalParticipationsCount = this.#computeTotalParticipation(this.sharedParticipationsCount, started, completed);
this.multipleSendings = multipleSendings;
}

get isTypeProfilesCollection() {
return this.type === CampaignTypes.PROFILES_COLLECTION;
}

get isTypeAssessment() {
return this.type === CampaignTypes.ASSESSMENT;
this.hasParticipation = this.totalParticipationsCount > 0;
}

#computeTotalParticipation(sharedParticipationsCount, started, completed) {
Expand Down
72 changes: 9 additions & 63 deletions api/src/prescription/campaign/domain/read-models/CampaignToJoin.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import { Assessment } from '../../../../shared/domain/models/Assessment.js';
import { CampaignTypes } from '../../../shared/domain/constants.js';
import { Campaign } from '../models/Campaign.js';

class CampaignToJoin {
class CampaignToJoin extends Campaign {
constructor({
id,
code,
title,
idPixLabel,
idPixType,
customLandingPageText,
externalIdHelpImageUrl,
alternativeTextToExternalIdHelpImage,
archivedAt,
deletedAt,
type,
isForAbsoluteNovice,
organizationId,
organizationName,
organizationType,
organizationLogoUrl,
Expand All @@ -27,70 +14,29 @@ class CampaignToJoin {
targetProfileName,
targetProfileImageUrl,
targetProfileIsSimplifiedAccess,
customResultPageText,
customResultPageButtonText,
customResultPageButtonUrl,
multipleSendings,
assessmentMethod,
...campaignAttributes
} = {}) {
this.id = id;
this.code = code;
this.title = title;
this.type = type;

this.targetProfileName = targetProfileName;
this.targetProfileImageUrl = targetProfileImageUrl;

this.customLandingPageText = customLandingPageText;
this.customResultPageButtonText = customResultPageButtonText;
this.customResultPageButtonUrl = customResultPageButtonUrl;
this.customResultPageText = customResultPageText;

this.externalIdHelpImageUrl = externalIdHelpImageUrl;
this.idPixLabel = idPixLabel;
this.idPixType = idPixType;
this.alternativeTextToExternalIdHelpImage = alternativeTextToExternalIdHelpImage;
this.isSimplifiedAccess = targetProfileIsSimplifiedAccess;
this.isForAbsoluteNovice = isForAbsoluteNovice;

this.identityProvider = identityProvider;

this.organizationId = organizationId;
super(campaignAttributes);
this.organizationName = organizationName;
this.organizationType = organizationType;
this.organizationLogoUrl = organizationLogoUrl;
this.organizationShowNPS = organizationShowNPS;
this.organizationFormNPSUrl = organizationFormNPSUrl;

this.multipleSendings = multipleSendings;
this.assessmentMethod = assessmentMethod;
this.targetProfileName = targetProfileName;
this.targetProfileImageUrl = targetProfileImageUrl;
this.isSimplifiedAccess = targetProfileIsSimplifiedAccess;

this.isRestricted = organizationIsManagingStudents || hasLearnersImportFeature;
this.archivedAt = archivedAt;
this.deletedAt = deletedAt;
this.identityProvider = identityProvider;

this.isRestricted = organizationIsManagingStudents || hasLearnersImportFeature;
this.reconciliationFields = null;
}

get isReconciliationRequired() {
return this.isRestricted && Array.isArray(this.reconciliationFields);
}

get isAssessment() {
return this.type === CampaignTypes.ASSESSMENT;
}

get isProfilesCollection() {
return this.type === CampaignTypes.PROFILES_COLLECTION;
}

get isAccessible() {
if (Boolean(this.archivedAt) || Boolean(this.deletedAt)) {
return false;
}
return true;
}

get isFlash() {
return this.assessmentMethod === Assessment.methods.FLASH;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const startWritingCampaignAssessmentResultsToStream = async function ({
const campaign = await campaignRepository.get(campaignId);
const translate = i18n.__;

if (!campaign.isAssessment()) {
if (!campaign.isAssessment) {
throw new CampaignTypeError();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const startWritingCampaignProfilesCollectionResultsToStream = async function ({
const translate = i18n.__;
let additionalHeaders = [];

//TODO: rewrite when we have only one model for Campaign, for now tests are based on Campaign.js from api context
if (!campaign.isProfilesCollection()) {
throw new CampaignTypeError();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const save = async function (campaigns, dependencies = { skillRepository }) {
latestCreatedCampaign.idPixType = params.type;
}

if (latestCreatedCampaign.isAssessment()) {
if (latestCreatedCampaign.isAssessment) {
const cappedTubes = await trx('target-profile_tubes')
.select('tubeId', 'level')
.where('targetProfileId', campaignAttributes.targetProfileId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const serialize = function (campaignManagement, meta) {
'customResultPageButtonUrl',
'sharedParticipationsCount',
'totalParticipationsCount',
'isTypeProfilesCollection',
'isProfilesCollection',
'isTypeAssessment',
'multipleSendings',
'isForAbsoluteNovice',
Expand Down
Loading

0 comments on commit dee799e

Please sign in to comment.