Skip to content

Commit

Permalink
Merge pull request #339 from mission-apprentissage/ui-server/retour-m…
Browse files Browse the repository at this point in the history
…ulticampagnes

[UI - server] Retours multicampagnes
  • Loading branch information
yohanngab authored Oct 29, 2024
2 parents d46faf0 + bae2b19 commit e1aa54b
Show file tree
Hide file tree
Showing 22 changed files with 118 additions and 168 deletions.
10 changes: 3 additions & 7 deletions server/src/controllers/campagnes.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import * as campagnesService from "../services/campagnes.service";
import tryCatch from "../utils/tryCatch.utils";

export const getCampagnes = tryCatch(async (req: any, res: any) => {

Check warning on line 7 in server/src/controllers/campagnes.controller.ts

View workflow job for this annotation

GitHub Actions / tests / Tests

Unexpected any. Specify a different type

Check warning on line 7 in server/src/controllers/campagnes.controller.ts

View workflow job for this annotation

GitHub Actions / tests / Tests

Unexpected any. Specify a different type
const isAdmin = req.user.role === USER_ROLES.ADMIN;
const isObserver = req.user.role === USER_ROLES.OBSERVER;
const scope = isObserver ? req.user.scope : null;
const userSiret = req.user?.etablissements?.map((etablissement) => etablissement.siret);

const page = req.body.page || 1;
const pageSize = req.body.pageSize || 10;

const diplome = req.body.diplome;
const etablissementFormateurSiret = req.body.siret;
const siret = req.body.siret;
const search = req.body.search;
const departement = req.body.departement;

Expand All @@ -24,18 +22,16 @@ export const getCampagnes = tryCatch(async (req: any, res: any) => {
query.diplome = diplome;
}

if (etablissementFormateurSiret) {
query.etablissementFormateurSiret = etablissementFormateurSiret;
if (siret) {
query.siret = siret;
}

if (departement) {
query.departement = departement;
}

const { success, body, ids, pagination } = await campagnesService.getCampagnes({
isAdmin,
isObserver,
userSiret,
scope,
page,
pageSize,
Expand Down
10 changes: 0 additions & 10 deletions server/src/controllers/etablissements.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,3 @@ export const getEtablissementsPublicStatistics = tryCatch(async (_req: any, res:

return res.status(200).json(body);
});

export const getEtablissementsWithCampagnesCount = tryCatch(async (req: any, res: any) => {
const userSiret = req.user?.etablissements?.map((etablissement) => etablissement.siret);

const { success, body } = await etablissementsService.getEtablissementsWithCampagnesCount({ userSiret });

if (!success) throw new BasicError();

return res.status(200).json(body);
});
10 changes: 8 additions & 2 deletions server/src/controllers/formations.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-nocheck -- TODO

import { USER_ROLES } from "../constants";
import { BasicError, ErrorMessage, FormationAlreadyExistingError, FormationNotFoundError } from "../errors";
import * as formationsService from "../services/formations.service";
import tryCatch from "../utils/tryCatch.utils";
Expand Down Expand Up @@ -60,10 +61,15 @@ export const updateFormation = tryCatch(async (req: any, res: any) => {
return res.status(200).json(body);
});

export const getFormationsDiplomesWithCampagnes = tryCatch(async (req: any, res: any) => {
export const getFormationsEtablissementsDiplomesWithCampagnesCount = tryCatch(async (req: any, res: any) => {
const isObserver = req.user?.role === USER_ROLES.OBSERVER;
const scope = isObserver ? req.user?.scope : null;
const userSiret = req.user?.etablissements?.map((etablissement) => etablissement.siret);

const { success, body } = await formationsService.getFormationsDiplomesWithCampagnes({ userSiret });
const { success, body } = await formationsService.getFormationsEtablissementsDiplomesWithCampagnesCount({
userSiret,
scope,
});

if (!success) throw new BasicError();

Expand Down
29 changes: 9 additions & 20 deletions server/src/dao/campagnes.dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import { getKbdClient } from "../db/db";
import type { ObserverScope } from "../types";

export const getAllWithTemoignageCountAndTemplateName = async ({
//siret,
query,
scope,
allowEmptyFilter = false,
}: {
//siret?: string[];
query: { diplome?: string; etablissementFormateurSiret?: string; departement?: string; campagneIds: string[] };
query: { diplome?: string[]; siret?: string[]; departement?: string; campagneIds: string[] };
scope?: ObserverScope;
allowEmptyFilter?: boolean;
}) => {
Expand Down Expand Up @@ -78,7 +76,10 @@ export const getAllWithTemoignageCountAndTemplateName = async ({
.leftJoin("etablissements", "formations.etablissement_id", "etablissements.id")
.where("campagnes.deleted_at", "is", null)
.where("formations.deleted_at", "is", null)
.groupBy(["campagnes.id", "questionnaires.id", "formations.id", "etablissements.id"]);
.where("etablissements.deleted_at", "is", null)
.where("temoignages.deleted_at", "is", null)
.groupBy(["campagnes.id", "questionnaires.id", "formations.id", "etablissements.id"])
.orderBy("campagnes.created_at", "desc");

if (scope && scope.field && scope.field !== "sirets" && scope.value) {
baseQuery = baseQuery.where(`formations.${scope.field}`, "=", scope.value);
Expand All @@ -95,30 +96,18 @@ export const getAllWithTemoignageCountAndTemplateName = async ({
baseQuery = baseQuery.where("formations.diplome", "in", ["INVALID_DIPLOME"]);
}

if (query && query.etablissementFormateurSiret?.length) {
baseQuery = baseQuery.where("formations.etablissement_formateur_siret", "in", query.etablissementFormateurSiret);
} else if (!allowEmptyFilter) {
// Force query to return no results by adding a false condition
baseQuery = baseQuery.where("formations.etablissement_formateur_siret", "in", ["INVALID_SIRET"]);
if (query && query.campagneIds?.length) {
baseQuery = baseQuery.where("campagnes.id", "in", query.campagneIds);
}

if (query && query.departement) {
baseQuery = baseQuery.where("formations.num_departement", "=", query.departement);
}

if (query && query.campagneIds?.length) {
baseQuery = baseQuery.where("campagnes.id", "in", query.campagneIds);
if (query && query?.siret?.length) {
baseQuery = baseQuery.where("formations.etablissement_formateur_siret", "in", query.siret);
}

/*if (siret) {
baseQuery = baseQuery.where((qb) =>
qb.or([
qb("formations.etablissement_gestionnaire_siret", "in", siret),
qb("formations.etablissement_formateur_siret", "in", siret),
])
);
}*/

return baseQuery.execute();
};

Expand Down
15 changes: 2 additions & 13 deletions server/src/dao/etablissements.dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ export const update = async (id: string, updatedEtablissement: Partial<Etablisse
return result.numUpdatedRows === BigInt(1);
};

export const findAllEtablissementWithCounts = async (
siret: string[]
): Promise<
export const findAllEtablissementWithCounts = async (): Promise<
(Pick<
Etablissement,
"id" | "created_at" | "enseigne" | "entreprise_raison_sociale" | "onisep_nom" | "region_implantation_nom" | "siret"
Expand All @@ -122,7 +120,7 @@ export const findAllEtablissementWithCounts = async (
verbatimsCount: number;
})[]
> => {
let baseQuery = getKbdClient()
const baseQuery = getKbdClient()
.selectFrom("etablissements")
.select([
"etablissements.id",
Expand Down Expand Up @@ -150,15 +148,6 @@ export const findAllEtablissementWithCounts = async (
.groupBy("etablissements.id")
.orderBy("campagnesCount", "desc");

if (siret?.length) {
baseQuery = baseQuery.where((qb) =>
qb.or([
qb("formations.etablissement_gestionnaire_siret", "in", siret),
qb("formations.etablissement_formateur_siret", "in", siret),
])
);
}

return baseQuery.execute();
};

Expand Down
15 changes: 13 additions & 2 deletions server/src/dao/formations.dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DeleteResult } from "kysely";
import { sql } from "kysely";

import { getKbdClient } from "../db/db";
import type { Formation } from "../types";
import type { Formation, ObserverScope } from "../types";

export const create = async (formation: Formation): Promise<{ id: string } | undefined> => {
return getKbdClient().insertInto("formations").values(formation).returning("id").executeTakeFirst();
Expand Down Expand Up @@ -293,7 +293,10 @@ export const findAllWithTemoignageCount = async (): Promise<Partial<Formation>[]
.execute();
};

export const findAllWithCampagnesCount = async (siret: string[]): Promise<Partial<Formation>[] | undefined> => {
export const findAllWithCampagnesCount = async (
siret: string[],
scope?: ObserverScope
): Promise<Partial<Formation>[] | undefined> => {
let baseQuery = getKbdClient()
.selectFrom("formations")
.leftJoin("formations_campagnes", "formations.id", "formations_campagnes.formation_id")
Expand Down Expand Up @@ -334,5 +337,13 @@ export const findAllWithCampagnesCount = async (siret: string[]): Promise<Partia
);
}

if (scope && scope.field && scope.field !== "sirets" && scope.value) {
baseQuery = baseQuery.where(`formations.${scope.field}`, "=", scope.value);
}

if (scope && scope.field && scope.field === "sirets" && scope.value.length) {
baseQuery = baseQuery.where(`formations.etablissement_gestionnaire_siret`, "in", scope.value);
}

return baseQuery.execute();
};
5 changes: 0 additions & 5 deletions server/src/routes/etablissements.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
getEtablissements,
getEtablissementsPublicStatistics,
getEtablissementsSuivi,
getEtablissementsWithCampagnesCount,
getEtablissementsWithTemoignageCount,
updateEtablissement,
} from "../controllers/etablissements.controller";
Expand All @@ -35,10 +34,6 @@ export const etablissements = () => {
}
);

router.get("/api/etablissements/with-campagnes-count", verifyUser, (req, res, next) => {
getEtablissementsWithCampagnesCount(req, res, next);
});

router.get("/api/etablissements/temoignage-count", (req, res, next) => {
getEtablissementsWithTemoignageCount(req, res, next);
});
Expand Down
6 changes: 3 additions & 3 deletions server/src/routes/formations.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
createFormation,
deleteFormation,
getFormations,
getFormationsDiplomesWithCampagnes,
getFormationsEtablissementsDiplomesWithCampagnesCount,
getFormationsWithTemoignageCount,
updateFormation,
} from "../controllers/formations.controller";
Expand Down Expand Up @@ -60,8 +60,8 @@ export const formations = () => {
}
);

router.get("/api/formations/diplomes-with-campagnes", verifyUser, (req, res, next) => {
getFormationsDiplomesWithCampagnes(req, res, next);
router.get("/api/formations/diplomes-and-etablissements-filters", verifyUser, (req, res, next) => {
getFormationsEtablissementsDiplomesWithCampagnesCount(req, res, next);
});

return router;
Expand Down
43 changes: 4 additions & 39 deletions server/src/services/campagnes.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-nocheck -- TODO

import { DIPLOME_TYPE_MATCHER, ETABLISSEMENT_NATURE, ETABLISSEMENT_RELATION_TYPE } from "../constants";
import { DIPLOME_TYPE_MATCHER } from "../constants";
import * as campagnesDao from "../dao/campagnes.dao";
import * as etablissementsDao from "../dao/etablissements.dao";
import * as formationsDao from "../dao/formations.dao";
Expand All @@ -9,53 +9,18 @@ import * as temoignagesDao from "../dao/temoignages.dao";
import * as verbatimsDao from "../dao/verbatims.dao";
import * as catalogue from "../modules/catalogue";
import * as pdfExport from "../modules/pdfExport";
import * as referentiel from "../modules/referentiel";
import * as xlsxExport from "../modules/xlsxExport";
import { appendDataWhenEmpty, getMedianDuration, getStatistics } from "../utils/campagnes.utils";
import { getChampsLibreField } from "../utils/verbatims.utils";

export const getCampagnes = async ({
isAdmin,
isObserver,
userSiret,
scope,
page = 1,
pageSize = 10,
query,
search,
}) => {
export const getCampagnes = async ({ isObserver, scope, page = 1, pageSize = 10, query, search }) => {
try {
let campagnes = [];

if (isAdmin) {
campagnes = await campagnesDao.getAllWithTemoignageCountAndTemplateName({ query });
} else if (isObserver) {
if (isObserver) {
campagnes = await campagnesDao.getAllWithTemoignageCountAndTemplateName({ scope, query });
} else {
const etablissementsFromReferentiel = await referentiel.getEtablissements(userSiret);

const allSirets = [];
for (const siret of userSiret) {
const etablissement = etablissementsFromReferentiel.find((etablissement) => etablissement.siret === siret);
if (!etablissement) continue;

const relatedSirets = [siret];
if (
[ETABLISSEMENT_NATURE.GESTIONNAIRE, ETABLISSEMENT_NATURE.GESTIONNAIRE_FORMATEUR].includes(
etablissement.nature
)
) {
relatedSirets.push(
...etablissement.relations
.filter((relation) => relation.type === ETABLISSEMENT_RELATION_TYPE.RESPONSABLE_FORMATEUR)
.map((etablissement) => etablissement.siret)
);
}
allSirets.push(...relatedSirets);
}

query.etablissementFormateurSiret = allSirets;
campagnes = await campagnesDao.getAllWithTemoignageCountAndTemplateName({ siret: allSirets, query });
campagnes = await campagnesDao.getAllWithTemoignageCountAndTemplateName({ query });
}

const unpaginatedCampagnesIds = campagnes.map((campagne) => campagne.id);
Expand Down
10 changes: 0 additions & 10 deletions server/src/services/etablissements.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,3 @@ export const getEtablissementsPublicStatistics = async () => {
return { success: false, body: error };
}
};

export const getEtablissementsWithCampagnesCount = async ({ userSiret }) => {
try {
const etablissements = await etablissementsDao.findAllEtablissementWithCounts(userSiret);

return { success: true, body: etablissements };
} catch (error) {
return { success: false, body: error };
}
};
35 changes: 31 additions & 4 deletions server/src/services/formations.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ export const updateFormation = async (id, updatedFormation) => {
}
};

export const getFormationsDiplomesWithCampagnes = async ({ userSiret }) => {
export const getFormationsEtablissementsDiplomesWithCampagnesCount = async ({ userSiret, scope }) => {
try {
const formations = await formationsDao.findAllWithCampagnesCount(userSiret);
const formations = await formationsDao.findAllWithCampagnesCount(userSiret, scope);

const formattedByDiplome = formations.reduce((acc, formation) => {
const diplome = formation.diplome || "N/A";
Expand All @@ -98,14 +98,41 @@ export const getFormationsDiplomesWithCampagnes = async ({ userSiret }) => {
return acc;
}, {});

const result = Object.keys(formattedByDiplome)
const formattedByEtablissement = formations.reduce((acc, formation) => {
const etablissementFormateurSiret = formation.etablissementFormateurSiret || "N/A";

if (!acc[etablissementFormateurSiret]) {
acc[etablissementFormateurSiret] = {
campagnesCount: 0,
etablissementFormateurEnseigne: formation.etablissementFormateurEnseigne,
etablissementFormateurEntrepriseRaisonSociale: formation.etablissementFormateurEntrepriseRaisonSociale,
etablissementFormateurSiret: formation.etablissementFormateurSiret,
};
}

acc[etablissementFormateurSiret].campagnesCount += formation.campagnesCount;

return acc;
}, {});

const diplomes = Object.keys(formattedByDiplome)
.map((diplome) => ({
intitule: diplome,
campagnesCount: formattedByDiplome[diplome],
}))
.sort((a, b) => b.campagnesCount - a.campagnesCount);

return { success: true, body: result };
const etablissements = Object.keys(formattedByEtablissement)
.map((etablissement) => ({
etablissementFormateurSiret: etablissement,
etablissementFormateurEnseigne: formattedByEtablissement[etablissement].etablissementFormateurEnseigne,
etablissementFormateurEntrepriseRaisonSociale:
formattedByEtablissement[etablissement].etablissementFormateurEntrepriseRaisonSociale,
campagnesCount: formattedByEtablissement[etablissement].campagnesCount,
}))
.sort((a, b) => b.campagnesCount - a.campagnesCount);

return { success: true, body: { diplomes, etablissements } };
} catch (error) {
return { success: false, body: error };
}
Expand Down
Loading

0 comments on commit e1aa54b

Please sign in to comment.