Skip to content

Commit

Permalink
feat: millesimes 2023 et salaires (#317)
Browse files Browse the repository at this point in the history
feat: millesimes 2023
feat: salaires
  • Loading branch information
K4ST0R authored Dec 23, 2024
1 parent f1e1058 commit 2e96fe9
Show file tree
Hide file tree
Showing 16 changed files with 126,961 additions and 117,003 deletions.
235,657 changes: 118,671 additions & 116,986 deletions server/data/acce_etablissements.csv

Large diffs are not rendered by default.

2,528 changes: 2,528 additions & 0 deletions server/data/depp-2022-etablissements-2022_2023-apprentissage.csv

Large diffs are not rendered by default.

5,606 changes: 5,606 additions & 0 deletions server/data/depp-2022-etablissements-2022_2023-pro.csv

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions server/migrations/20241219125144-salaire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { omit, without, uniq } from "lodash-es";
import { integer } from "#src/common/db/collections/jsonSchema/jsonSchemaTypes.js";
import * as MongoDB from "#src/common/db/mongodb.js";

const schema = {
properties: {
salaire_12_mois_q1: integer(),
salaire_12_mois_q2: integer(),
salaire_12_mois_q3: integer(),
},
required: [],
};

export const up = async (db, client) => {
MongoDB.setMongoDBClient(client);
await Promise.all([
MongoDB.mergeSchema("certificationsStats", schema),
MongoDB.mergeSchema("formationsStats", schema),
MongoDB.mergeSchema("regionalesStats", schema),
]);
};

export const down = async (db, client) => {
return Promise.all(
["certificationsStats", "formationsStats", "regionalesStats"].map(async (collection) => {
const collectionInfos = await db.listCollections({ name: collection }).toArray();
const validator = collectionInfos[0].options.validator;

if (!validator) {
return;
}

const oldSchema = validator.$jsonSchema;
const newSchema = {
...oldSchema,
properties: omit(oldSchema.properties, Object.keys(schema.properties)),
required: uniq(without(oldSchema.required || [], ...schema.required)),
};

return db.command({
collMod: collection,
validationLevel: "strict",
validationAction: "error",
validator: {
$jsonSchema: newSchema,
},
});
})
);
};
7 changes: 7 additions & 0 deletions server/src/common/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export const INSERJEUNES_STATS_NAMES = [
"nb_poursuite_etudes",
"nb_sortant",
"taux_rupture_contrats",
"salaire_12_mois_q1",
"salaire_12_mois_q2",
"salaire_12_mois_q3",
];
export const INSERJEUNES_IGNORED_STATS_NAMES = [
"taux_poursuite_etudes",
Expand All @@ -26,6 +29,9 @@ export const INSERJEUNES_IGNORED_STATS_NAMES = [
"salaire_TS_Q1_12_mois",
"salaire_TS_Q2_12_mois",
"salaire_TS_Q3_12_mois",
"salaire_TS_Q1_12_mois_prec",
"salaire_TS_Q2_12_mois_prec",
"salaire_TS_Q3_12_mois_prec",
];

export const INSERSUP_STATS_NAMES = [
Expand Down Expand Up @@ -60,6 +66,7 @@ export const CUSTOM_STATS_NAMES = [
];

export const ALL = /.*/;
export const ALL_WITHOUT_INCOME = /^(?!salaire_).*/;
export const TAUX = /^taux_.*$/;
export const VALEURS = /^nb_.*$/;

Expand Down
4 changes: 2 additions & 2 deletions server/src/common/utils/csvUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ export function parseCsv(options = {}) {
});
}

export function getStatsAsColumns() {
return getStats(ALL, (statName) => (f) => f[statName]);
export function getStatsAsColumns(keyRegex = ALL) {
return getStats(keyRegex, (statName) => (f) => f[statName]);
}
12 changes: 9 additions & 3 deletions server/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,16 @@ const config = {
},
},
millesimes: {
default: env.get("TRAJECTOIRES_PRO_MILLESIMES").default("2020,2021,2022").asArray(),
formations: env.get("TRAJECTOIRES_PRO_MILLESIMES_FORMATIONS").default("2019_2020,2020_2021,2021_2022").asArray(),
default: env.get("TRAJECTOIRES_PRO_MILLESIMES").default("2020,2021,2022,2023").asArray(),
formations: env
.get("TRAJECTOIRES_PRO_MILLESIMES_FORMATIONS")
.default("2019_2020,2020_2021,2021_2022,2022_2023")
.asArray(),
formationsSup: env.get("MILLESIMES_FORMATIONS_SUP").default("2019_2020,2020_2021,2021_2022").asArray(),
regionales: env.get("TRAJECTOIRES_PRO_MILLESIMES_REGIONALES").default("2019_2020,2020_2021,2021_2022").asArray(),
regionales: env
.get("TRAJECTOIRES_PRO_MILLESIMES_REGIONALES")
.default("2019_2020,2020_2021,2021_2022,2022_2023")
.asArray(),
},
widget: {
plausibleDomain: env
Expand Down
3 changes: 2 additions & 1 deletion server/src/http/routes/formationsRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getMillesimeFormationsYearFrom,
transformDisplayStat,
isMillesimesYearSingle,
ALL_WITHOUT_INCOME,
} from "#src/common/stats.js";
import BCNRepository from "#src/common/repositories/bcn.js";
import BCNSiseRepository from "#src/common/repositories/bcnSise.js";
Expand Down Expand Up @@ -161,7 +162,7 @@ export default () => {
millesime: (f) => f.millesime,
donnee_source_type: (f) => f.donnee_source.type,
donnee_source_code_certification: (f) => f.donnee_source.code_certification,
...getStatsAsColumns(),
...getStatsAsColumns(ALL_WITHOUT_INCOME),
},
mapper: (v) => (v === null ? "null" : v),
});
Expand Down
4 changes: 2 additions & 2 deletions server/src/http/routes/regionalesRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
sendImageOnError,
} from "#src/http/utils/responseUtils.js";
import BCNRepository from "#src/common/repositories/bcn.js";
import { getLastMillesimesRegionales, transformDisplayStat } from "#src/common/stats.js";
import { ALL_WITHOUT_INCOME, getLastMillesimesRegionales, transformDisplayStat } from "#src/common/stats.js";
import { getStatsAsColumns } from "#src/common/utils/csvUtils.js";
import RegionaleStatsRepository from "#src/common/repositories/regionaleStats.js";
import { ErrorRegionaleNotFound, ErrorNoDataForMillesime, ErrorFormationNotExist } from "#src/http/errors.js";
Expand Down Expand Up @@ -84,7 +84,7 @@ export default () => {
millesime: (f) => f.millesime,
donnee_source_type: (f) => f.donnee_source.type,
donnee_source_code_certification: (f) => f.donnee_source.code_certification,
...getStatsAsColumns(),
...getStatsAsColumns(ALL_WITHOUT_INCOME),
},
mapper: (v) => (v === null ? "null" : v),
});
Expand Down
12 changes: 12 additions & 0 deletions server/src/http/routes/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,18 @@ components:
taux_autres_24_mois:
type: number
nullable: true
salaire_12_mois_q1:
type: number
nullable: true
description: "en euros, 1er quartile du salaire net mensuel à 12 mois des sortants en emploi retrouvés dans la Base Tous Salariés (BTS)"
salaire_12_mois_q2:
type: number
description: "en euros, 2ème quartile du salaire net mensuel à 12 mois des sortants en emploi retrouvés dans la Base Tous Salariés (BTS)"
nullable: true
salaire_12_mois_q3:
type: number
nullable: true
description: "en euros, 3ème quartile du salaire net mensuel à 12 mois des sortants en emploi retrouvés dans la Base Tous Salariés (BTS)"
_meta:
$ref: "#/components/schemas/Meta"

Expand Down
2 changes: 1 addition & 1 deletion server/src/jobs/stats/computeContinuumStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export async function computeContinuumStats(options = {}) {

await oleoduc(
mergeStreams(stats.map(streamStats)),
filterData(({ data }) => data.donnee_source.type === "self" && (!millesime || data.millesime === millesime)),
filterData(({ data }) => data?.donnee_source?.type === "self" && (!millesime || data.millesime === millesime)),
transformData(async ({ data, statName }) => {
const query = { ...getQueryForStats({ data, statName, millesime: data.millesime }) };

Expand Down
20 changes: 20 additions & 0 deletions server/src/services/inserjeunes/InserJeunes.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,25 @@ function computeMissingStats() {
});
}

function renameStats() {
return transformData((data) => {
const statsToRename = {
salaire_TS_Q1_12_mois: "salaire_12_mois_q1",
salaire_TS_Q2_12_mois: "salaire_12_mois_q2",
salaire_TS_Q3_12_mois: "salaire_12_mois_q3",
};

return {
...data,
...Object.fromEntries(
Object.entries(data)
.filter(([k]) => statsToRename[k])
.map(([k, d]) => [statsToRename[k], d])
),
};
});
}

async function transformApiStats(statsFromApi, groupBy) {
let stats = [];
await oleoduc(
Expand All @@ -94,6 +113,7 @@ async function transformApiStats(statsFromApi, groupBy) {
groupBy,
flattenArray(),
computeMissingStats(),
renameStats(),
writeData((data) => {
stats.push(data);
})
Expand Down
35 changes: 30 additions & 5 deletions server/tests/http/certificationsRoutes-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ describe("certificationsRoutes", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
});

const response = await httpClient.get(`/api/inserjeunes/certifications`, {
Expand Down Expand Up @@ -82,6 +85,9 @@ describe("certificationsRoutes", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
formation_fermee: false,
donnee_source: {
code_certification: "12345678",
Expand Down Expand Up @@ -263,6 +269,9 @@ describe("certificationsRoutes", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
});

const response = await httpClient.get(`/api/inserjeunes/certifications.csv`, {
Expand All @@ -275,9 +284,12 @@ describe("certificationsRoutes", () => {
assert.strictEqual(response.headers["content-type"], "text/csv; charset=UTF-8");
assert.deepStrictEqual(
response.data,
`code_certification;code_formation_diplome;filiere;millesime;donnee_source_type;donnee_source_code_certification;nb_annee_term;nb_en_emploi_12_mois;nb_en_emploi_18_mois;nb_en_emploi_24_mois;nb_en_emploi_6_mois;nb_poursuite_etudes;nb_sortant;taux_autres_12_mois;taux_autres_18_mois;taux_autres_24_mois;taux_autres_6_mois;taux_en_emploi_12_mois;taux_en_emploi_18_mois;taux_en_emploi_24_mois;taux_en_emploi_6_mois;taux_en_formation;taux_rupture_contrats
12345678;12345678;apprentissage;2020;self;12345678;19;4;3;2;5;1;6;null;null;null;null;null;null;null;null;null;null
`
`code_certification;code_formation_diplome;filiere;millesime;donnee_source_type;donnee_source_code_certification;` +
`nb_annee_term;nb_en_emploi_12_mois;nb_en_emploi_18_mois;nb_en_emploi_24_mois;nb_en_emploi_6_mois;nb_poursuite_etudes;` +
`nb_sortant;salaire_12_mois_q1;salaire_12_mois_q2;salaire_12_mois_q3;taux_autres_12_mois;taux_autres_18_mois;` +
`taux_autres_24_mois;taux_autres_6_mois;taux_en_emploi_12_mois;taux_en_emploi_18_mois;taux_en_emploi_24_mois;` +
`taux_en_emploi_6_mois;taux_en_formation;taux_rupture_contrats\n` +
`12345678;12345678;apprentissage;2020;self;12345678;19;4;3;2;5;1;6;18;19;20;null;null;null;null;null;null;null;null;null;null\n`
);
});

Expand Down Expand Up @@ -305,6 +317,9 @@ describe("certificationsRoutes", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
});

const response = await httpClient.get(`/api/inserjeunes/certifications.csv`, {
Expand All @@ -317,8 +332,12 @@ describe("certificationsRoutes", () => {
assert.strictEqual(response.headers["content-type"], "text/csv; charset=UTF-8");
assert.deepStrictEqual(
response.data,
`code_certification;code_formation_diplome;filiere;millesime;donnee_source_type;donnee_source_code_certification;nb_annee_term;nb_en_emploi_12_mois;nb_en_emploi_18_mois;nb_en_emploi_24_mois;nb_en_emploi_6_mois;nb_poursuite_etudes;nb_sortant;taux_autres_12_mois;taux_autres_18_mois;taux_autres_24_mois;taux_autres_6_mois;taux_en_emploi_12_mois;taux_en_emploi_18_mois;taux_en_emploi_24_mois;taux_en_emploi_6_mois;taux_en_formation;taux_rupture_contrats
12345678;12345678;apprentissage;2020;self;12345678;100;4;3;2;5;1;6;14;15;16;13;11;10;9;12;8;7
`code_certification;code_formation_diplome;filiere;millesime;donnee_source_type;donnee_source_code_certification;` +
`nb_annee_term;nb_en_emploi_12_mois;nb_en_emploi_18_mois;nb_en_emploi_24_mois;nb_en_emploi_6_mois;` +
`nb_poursuite_etudes;nb_sortant;salaire_12_mois_q1;salaire_12_mois_q2;salaire_12_mois_q3;taux_autres_12_mois;` +
`taux_autres_18_mois;taux_autres_24_mois;taux_autres_6_mois;taux_en_emploi_12_mois;taux_en_emploi_18_mois;` +
`taux_en_emploi_24_mois;taux_en_emploi_6_mois;taux_en_formation;taux_rupture_contrats
12345678;12345678;apprentissage;2020;self;12345678;100;4;3;2;5;1;6;18;19;20;14;15;16;13;11;10;9;12;8;7
`
);
});
Expand Down Expand Up @@ -439,6 +458,9 @@ describe("certificationsRoutes", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
});
await insertCertificationsStats({ code_certification: "12345678", millesime: "2019" });

Expand Down Expand Up @@ -470,6 +492,9 @@ describe("certificationsRoutes", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
formation_fermee: false,
donnee_source: {
code_certification: "12345678",
Expand Down
6 changes: 6 additions & 0 deletions server/tests/jobs/stats/computeContinuumStats-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ describe("computeContinuumStats", () => {
taux_en_emploi_6_mois: 90,
taux_en_formation: 10,
taux_rupture_contrats: 10,
salaire_12_mois_q1: 19,
salaire_12_mois_q2: 20,
salaire_12_mois_q3: 21,
};

const DEFAULT_STATS_VARIANT = {
Expand All @@ -59,6 +62,9 @@ describe("computeContinuumStats", () => {
taux_en_emploi_6_mois: 50,
taux_en_formation: 25,
taux_rupture_contrats: 10,
salaire_12_mois_q1: 19,
salaire_12_mois_q2: 20,
salaire_12_mois_q3: 21,
};

describe("Certifications", () => {
Expand Down
12 changes: 12 additions & 0 deletions server/tests/jobs/stats/computeUAI-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ describe("computeUAI", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 17,
salaire_12_mois_q2: 18,
salaire_12_mois_q3: 19,
});

await insertFormationsStats({
Expand All @@ -495,6 +498,9 @@ describe("computeUAI", () => {
taux_autres_12_mois: 15,
taux_autres_18_mois: 16,
taux_autres_24_mois: 17,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
});

const result = await computeUAI();
Expand Down Expand Up @@ -549,6 +555,9 @@ describe("computeUAI", () => {
taux_autres_12_mois: 14,
taux_autres_18_mois: 15,
taux_autres_24_mois: 16,
salaire_12_mois_q1: 17,
salaire_12_mois_q2: 18,
salaire_12_mois_q3: 19,
},
{
uai: "ABCD1234",
Expand Down Expand Up @@ -578,6 +587,9 @@ describe("computeUAI", () => {
taux_autres_12_mois: 15,
taux_autres_18_mois: 16,
taux_autres_24_mois: 17,
salaire_12_mois_q1: 18,
salaire_12_mois_q2: 19,
salaire_12_mois_q3: 20,
},
]
);
Expand Down
6 changes: 3 additions & 3 deletions server/tests/utils/fakeData.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
users,
CAFormations,
} from "#src/common/db/collections/collections.js";
import { ALL, getStatsCompute } from "#src/common/stats.js";
import { ALL, ALL_WITHOUT_INCOME, getStatsCompute } from "#src/common/stats.js";
import { hashPassword } from "#src/services/auth/auth.js";
import { ObjectId } from "mongodb";

Expand Down Expand Up @@ -80,7 +80,7 @@ export function insertRegionalesStats(custom = {}, withStat = true) {
code_formation_diplome: createCodeFormationDiplome(),
libelle: "LIBELLE",
diplome: { code: "4", libelle: "BAC" },
...(withStat ? getStatsCompute(ALL, () => generateStatValue()) : {}),
...(withStat ? getStatsCompute(ALL_WITHOUT_INCOME, () => generateStatValue()) : {}),
donnee_source: {
code_certification,
type: "self",
Expand Down Expand Up @@ -115,7 +115,7 @@ export function insertFormationsStats(custom = {}, withStat = true) {
code_formation_diplome: createCodeFormationDiplome(),
libelle: "LIBELLE",
diplome: { code: "4", libelle: "BAC" },
...(withStat ? getStatsCompute(ALL, () => generateStatValue()) : {}),
...(withStat ? getStatsCompute(ALL_WITHOUT_INCOME, () => generateStatValue()) : {}),
region: { code: "11", nom: "Île-de-France" },
academie: {
code: "01",
Expand Down

0 comments on commit 2e96fe9

Please sign in to comment.