Skip to content

Commit

Permalink
fix: filtrage offre par niveau remonte les indifférents (#745)
Browse files Browse the repository at this point in the history
  • Loading branch information
alanlr authored Oct 27, 2023
1 parent 58c0835 commit 96fa6da
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 153 deletions.
1 change: 1 addition & 0 deletions server/src/services/constant.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const OPCOS = {
}

export const NIVEAUX_POUR_LBA = {
INDIFFERENT: "Indifférent",
"3 (CAP...)": "Cap, autres formations niveau (Infrabac)",
"4 (BAC...)": "BP, Bac, autres formations niveau (Bac)",
"5 (BTS, DEUST...)": "BTS, DEUST, autres formations niveau (Bac+2)",
Expand Down
151 changes: 1 addition & 150 deletions server/src/services/formulaire.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,17 @@ import { IDelegation, IJob, IJobWritable, IRecruiter, IUserRecruteur, JOB_STATUS
import { getRomeDetailsFromAPI } from "@/common/apis/Pe"
import { getStaticFilePath } from "@/common/utils/getStaticFilePath"

import { search } from "../common/esClient/index"
import { Recruiter, UnsubscribeOF } from "../common/model/index"
import { asyncForEach } from "../common/utils/asyncUtils"
import config from "../config"

import { getCatalogueEtablissements, getCatalogueFormations } from "./catalogue.service"
import { ACTIVE, ETAT_UTILISATEUR, RECRUITER_STATUS } from "./constant.service"
import { ETAT_UTILISATEUR, RECRUITER_STATUS } from "./constant.service"
import dayjs from "./dayjs.service"
import { getEtablissement, sendEmailConfirmationEntreprise } from "./etablissement.service"
import { ILbaJobEsResult } from "./lbajob.service.types"
import mailer from "./mailer.service"
import { getUser, getUserStatus } from "./userRecruteur.service"

const JOB_SEARCH_LIMIT = 250

interface IFormulaireExtended extends IRecruiter {
entreprise_localite?: string
}
Expand All @@ -31,151 +27,6 @@ export interface IOffreExtended extends IJob {
supprimer: string
}

/**
* @description get filtered jobs from elastic search index
* @param {Object} payload
* @param {number} payload.distance
* @param {string} payload.lat
* @param {string} payload.long
* @param {string[]} payload.romes
* @param {string} payload.niveau
* @returns {Promise<ILbaJobEsResult[]>}
*/
export const getJobsFromElasticSearch = async ({
distance,
lat,
lon,
romes,
niveau,
}: {
distance: number
lat: string
lon: string
romes: string[]
niveau: string
}): Promise<ILbaJobEsResult[]> => {
const filter: Array<object> = [
{
geo_distance: {
distance: `${distance}km`,
geo_coordinates: {
lat,
lon,
},
},
},
]

if (niveau && niveau !== "Indifférent") {
filter.push({
nested: {
path: "jobs",
query: {
bool: {
must: [
{
match_phrase: {
"jobs.job_level_label": niveau,
},
},
],
},
},
},
})
}

const body = {
query: {
bool: {
must: [
{
nested: {
path: "jobs",
query: {
bool: {
must: [
{
match: {
"jobs.rome_code": romes.join(" "),
},
},
{
match: {
"jobs.job_status": ACTIVE,
},
},
],
},
},
},
},
{
match: {
status: "Actif",
},
},
],
filter: filter,
},
},
sort: [
{
_geo_distance: {
geo_coordinates: {
lat,
lon,
},
order: "asc",
unit: "km",
mode: "min",
distance_type: "arc",
ignore_unmapped: true,
},
},
],
}

const result = await search({ size: JOB_SEARCH_LIMIT, index: "recruiters", body }, Recruiter)

const filteredJobs = await Promise.all(
result.map(async (x) => {
const jobs: any[] = []

if (x._source.jobs.length === 0) {
return
}

if (x._source.is_delegated) {
const [establishment_location] = x._source.address.match(/([0-9]{5})[ ,] ?([a-zA-Z-]*)/) ?? [""]
const cfa = await getEtablissement({ establishment_siret: x._source.cfa_delegated_siret })

x._source.phone = cfa?.phone
x._source.email = cfa?.email
x._source.last_name = cfa?.last_name
x._source.first_name = cfa?.first_name
x._source.establishment_raison_sociale = cfa?.establishment_raison_sociale
x._source.address = cfa?.address
x._source.establishment_location = establishment_location
}

x._source.jobs.forEach((o) => {
if (romes.some((item) => o.rome_code.includes(item)) && o.job_status === JOB_STATUS.ACTIVE) {
o.rome_label = o.rome_appellation_label ?? o.rome_label
if (!niveau || niveau === "Indifférent" || niveau === o.job_level_label) {
jobs.push(o)
}
}
})

x._source.jobs = jobs
return x
})
)

return filteredJobs
}

/**
* @description get formulaire by offer id
*/
Expand Down
162 changes: 159 additions & 3 deletions server/src/services/lbajob.service.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,176 @@
import { IJob, IRecruiter, JOB_STATUS } from "shared"

import { Recruiter } from "@/common/model"

import { search } from "../common/esClient/index"
import { encryptMailWithIV } from "../common/utils/encryptString"
import { IApiError, manageApiError } from "../common/utils/errorManager"
import { roundDistance } from "../common/utils/geolib"
import { trackApiCall } from "../common/utils/sendTrackingEvent"
import { sentryCaptureException } from "../common/utils/sentryUtils"

import { IApplicationCount, getApplicationByJobCount } from "./application.service"
import { NIVEAUX_POUR_LBA, RECRUITER_STATUS } from "./constant.service"
import { getJobsFromElasticSearch, getOffreAvecInfoMandataire, incrementLbaJobViewCount } from "./formulaire.service"
import { ACTIVE, NIVEAUX_POUR_LBA, RECRUITER_STATUS } from "./constant.service"
import { getEtablissement } from "./etablissement.service"
import { getOffreAvecInfoMandataire, incrementLbaJobViewCount } from "./formulaire.service"
import { ILbaItemLbaJob } from "./lbaitem.shared.service.types"
import type { ILbaJobEsResult } from "./lbajob.service.types"
import { ILbaJobEsResult } from "./lbajob.service.types"
import { filterJobsByOpco } from "./opco.service"

const JOB_SEARCH_LIMIT = 250

const coordinatesOfFrance = [2.213749, 46.227638]

/**
* @description get filtered jobs from elastic search index
* @param {Object} payload
* @param {number} payload.distance
* @param {string} payload.lat
* @param {string} payload.long
* @param {string[]} payload.romes
* @param {string} payload.niveau
* @returns {Promise<ILbaJobEsResult[]>}
*/
export const getJobsFromElasticSearch = async ({
distance,
lat,
lon,
romes,
niveau,
}: {
distance: number
lat: string
lon: string
romes: string[]
niveau: string
}): Promise<ILbaJobEsResult[]> => {
const filter: Array<object> = [
{
geo_distance: {
distance: `${distance}km`,
geo_coordinates: {
lat,
lon,
},
},
},
]

if (niveau && niveau !== "Indifférent") {
filter.push({
nested: {
path: "jobs",
query: {
bool: {
should: [
{
match_phrase: {
"jobs.job_level_label": niveau,
},
},
{
match_phrase: {
"jobs.job_level_label": NIVEAUX_POUR_LBA["INDIFFERENT"],
},
},
],
},
},
},
})
}

const body = {
query: {
bool: {
must: [
{
nested: {
path: "jobs",
query: {
bool: {
must: [
{
match: {
"jobs.rome_code": romes.join(" "),
},
},
{
match: {
"jobs.job_status": ACTIVE,
},
},
],
},
},
},
},
{
match: {
status: "Actif",
},
},
],
filter: filter,
},
},
sort: [
{
_geo_distance: {
geo_coordinates: {
lat,
lon,
},
order: "asc",
unit: "km",
mode: "min",
distance_type: "arc",
ignore_unmapped: true,
},
},
],
}

const result = await search({ size: JOB_SEARCH_LIMIT, index: "recruiters", body }, Recruiter)

const filteredJobs = await Promise.all(
result.map(async (x) => {
const jobs: any[] = []

if (x._source.jobs.length === 0) {
return
}

if (x._source.is_delegated) {
const [establishment_location] = x._source.address.match(/([0-9]{5})[ ,] ?([a-zA-Z-]*)/) ?? [""]
const cfa = await getEtablissement({ establishment_siret: x._source.cfa_delegated_siret })

x._source.phone = cfa?.phone
x._source.email = cfa?.email
x._source.last_name = cfa?.last_name
x._source.first_name = cfa?.first_name
x._source.establishment_raison_sociale = cfa?.establishment_raison_sociale
x._source.address = cfa?.address
x._source.establishment_location = establishment_location
}

x._source.jobs.forEach((o) => {
if (romes.some((item) => o.rome_code.includes(item)) && o.job_status === JOB_STATUS.ACTIVE) {
o.rome_label = o.rome_appellation_label ?? o.rome_label
if (!niveau || NIVEAUX_POUR_LBA["INDIFFERENT"] === o.job_level_label || niveau === o.job_level_label) {
jobs.push(o)
}
}
})

x._source.jobs = jobs
return x
})
)

return filteredJobs
}

/**
* Retourne les offres LBA correspondantes aux critères de recherche
*/
Expand Down

0 comments on commit 96fa6da

Please sign in to comment.