Skip to content

Commit

Permalink
feat: get accessibilite from acces libre database (#87)
Browse files Browse the repository at this point in the history
* feat: get accessibilite from acces libre database

* fix: reduce size of database of acces libre
  • Loading branch information
abelkhay authored Jul 3, 2023
1 parent 8d092f0 commit db48660
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 15 deletions.
3 changes: 3 additions & 0 deletions assets/input/data-inclusion/data-inclusion.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
"prise_rdv": {
"colonne": "prise_rdv"
},
"accessibilite": {
"colonne": "accessibilite"
},
"labels_nationaux": [
{
"colonnes": ["labels_nationaux"],
Expand Down
15 changes: 11 additions & 4 deletions src/transformer/cli/action/transformer.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Report } from '../../report';
import { toLieuxMediationNumerique, validValuesOnly } from '../../input';
import { writeErrorsOutputFiles, writeOutputFiles } from '../../output';
import { TransformerOptions } from '../transformer-options';
import { Erp } from '../../fields';

/* eslint-disable max-lines-per-function, max-statements, @typescript-eslint/strict-boolean-expressions */
/* eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/typedef, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
Expand Down Expand Up @@ -78,6 +79,11 @@ const replaceNullWithEmptyString = (jsonString: string): string => {
return JSON.stringify(jsonObj, replacer);
};

const fetchAccesLibreData = async (): Promise<string> =>
JSON.stringify(
(await axios.get('https://anct-carto-client-feature-les-assembleurs.s3.eu-west-3.amazonaws.com/acceslibre.json')).data
);

export const transformerAction = async (transformerOptions: TransformerOptions): Promise<void> => {
await Promise.all([
transformerOptions.source.startsWith('http')
Expand All @@ -87,11 +93,13 @@ export const transformerAction = async (transformerOptions: TransformerOptions):
transformerOptions.delimiter ?? ''
)
: await readFrom(transformerOptions.source.split('@')),
fs.promises.readFile(transformerOptions.configFile, 'utf-8')
]).then(([input, matching]: [string, string]): void => {
fs.promises.readFile(transformerOptions.configFile, 'utf-8'),
await fetchAccesLibreData()
]).then(([input, matching, accesLibreData]: [string, string, string]): void => {
const accesLibreErps: Erp[] = JSON.parse(accesLibreData);
const lieuxDeMediationNumerique: LieuMediationNumerique[] = JSON.parse(replaceNullWithEmptyString(input))
.map(flatten)
.map(toLieuxMediationNumerique(matching, transformerOptions.sourceName, REPORT))
.map(toLieuxMediationNumerique(matching, transformerOptions.sourceName, REPORT, accesLibreErps))
.filter(validValuesOnly);

const lieuxDeMediationNumeriqueFiltered: LieuMediationNumeriqueById = lieuxDeMediationNumerique.reduce(
Expand All @@ -103,7 +111,6 @@ export const transformerAction = async (transformerOptions: TransformerOptions):
);

const lieuxDeMediationNumeriqueWithSingleIds: LieuMediationNumerique[] = Object.values(lieuxDeMediationNumeriqueFiltered);

writeErrorsOutputFiles({
path: transformerOptions.outputDirectory,
name: transformerOptions.sourceName,
Expand Down
73 changes: 69 additions & 4 deletions src/transformer/fields/accessibilite/accessibilite.field.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/naming-convention, camelcase */

import { Adresse } from '@gouvfr-anct/lieux-de-mediation-numerique';
import { LieuxMediationNumeriqueMatching, DataSource } from '../../input';
import { processAccessibilite } from './accessibilite.field';
import { Erp, processAccessibilite } from './accessibilite.field';

describe('accessibilite field', (): void => {
it('should get accessibilite url from data source using matching information', (): void => {
Expand All @@ -11,11 +12,19 @@ describe('accessibilite field', (): void => {
}
} as LieuxMediationNumeriqueMatching;

const adresseProcessed: Adresse = {
voie: '',
code_postal: '',
commune: ''
} as Adresse;

const source: DataSource = {
bf_accessibilit_: 'https://acceslibre.beta.gouv.fr/app/73-chambery/a/administration-publique/erp/mairie-chambery/'
};

const accessibilite: string | undefined = processAccessibilite(source, matching);
const accesLibreData: Erp[] = [];

const accessibilite: string | undefined = processAccessibilite(source, matching, accesLibreData, adresseProcessed);

expect(accessibilite).toBe(
'https://acceslibre.beta.gouv.fr/app/73-chambery/a/administration-publique/erp/mairie-chambery/'
Expand All @@ -29,9 +38,17 @@ describe('accessibilite field', (): void => {
}
} as LieuxMediationNumeriqueMatching;

const adresseProcessed: Adresse = {
voie: '',
code_postal: '',
commune: ''
} as Adresse;

const source: DataSource = {};

const accessibilite: string | undefined = processAccessibilite(source, matching);
const accesLibreData: Erp[] = [];

const accessibilite: string | undefined = processAccessibilite(source, matching, accesLibreData, adresseProcessed);

expect(accessibilite).toBeUndefined();
});
Expand All @@ -43,11 +60,59 @@ describe('accessibilite field', (): void => {
}
} as LieuxMediationNumeriqueMatching;

const adresseProcessed: Adresse = {
voie: '',
code_postal: '',
commune: ''
} as Adresse;

const source: DataSource = {
bf_accessibilit_: ''
};
const accessibilite: string | undefined = processAccessibilite(source, matching);

const accesLibreData: Erp[] = [];

const accessibilite: string | undefined = processAccessibilite(source, matching, accesLibreData, adresseProcessed);

expect(accessibilite).toBeUndefined();
});

it('should get accessibilite from acces libre', (): void => {
const matching: LieuxMediationNumeriqueMatching = {
accessibilite: {
colonne: 'bf_accessibilit_'
},
nom: {
colonne: 'nom'
}
} as LieuxMediationNumeriqueMatching;

const adresseProcessed: Adresse = {
voie: '31 rue Jean Gallart',
code_postal: '49650',
commune: 'Allonnes'
} as Adresse;

const source: DataSource = {
bf_accessibilit_: '',
nom: "France Services d'Allonnes"
};

const accesLibreData: Erp[] = [
{
name: 'France Services Allonnes',
siret: '',
web_url: 'https://acceslibre.beta.gouv.fr/app/49-allonnes/a/guichet-france-services/erp/france-services/',
voie: 'jean gallart',
numero: '31',
postal_code: '49650'
}
];

const accessibilite: string | undefined = processAccessibilite(source, matching, accesLibreData, adresseProcessed);

expect(accessibilite).toBe(
'https://acceslibre.beta.gouv.fr/app/49-allonnes/a/guichet-france-services/erp/france-services/'
);
});
});
51 changes: 48 additions & 3 deletions src/transformer/fields/accessibilite/accessibilite.field.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,53 @@
import { Url } from '@gouvfr-anct/lieux-de-mediation-numerique';
/* eslint-disable @typescript-eslint/naming-convention */

import { Adresse, Url } from '@gouvfr-anct/lieux-de-mediation-numerique';
import { LieuxMediationNumeriqueMatching, DataSource, Colonne } from '../../input';
import { ratio } from 'fuzzball';

export type Erp = {
name: string;
siret: string;
web_url: string;
voie: string;
numero: string;
postal_code: string;
};

const getAccessibiliteFromAccesLibre = (
source: DataSource,
matching: LieuxMediationNumeriqueMatching,
accesLibreData: Erp[],
adresseProcessed: Adresse
): Url | undefined => {
const erpMatchWithScores: Erp[] = accesLibreData
.filter((erp: Erp): boolean => erp.postal_code === adresseProcessed.code_postal)
.filter(
(erp: Erp): boolean =>
ratio(source[matching.nom.colonne] ?? '', erp.name) > 60 ||
ratio(adresseProcessed.voie, erp.numero.concat(' ', erp.voie)) > 60
);

const accesLibreUrlByFuzzyMatch: string | undefined =
erpMatchWithScores.length === 1 ? erpMatchWithScores[0]?.web_url : undefined;
const currentPivot: string | undefined =
matching.pivot?.colonne != null && source[matching.pivot.colonne] !== '' ? source[matching.pivot.colonne] : undefined;
const accesLibreUrlBySiretMatch: string | undefined =
erpMatchWithScores.find((erp: Erp): boolean => erp.siret === currentPivot)?.web_url ?? undefined;

const accesLibreUrl: string | undefined = accesLibreUrlBySiretMatch ?? accesLibreUrlByFuzzyMatch ?? undefined;

return accesLibreUrl == null ? undefined : Url(accesLibreUrl);
};

const canProcessAccessibilite = (source: DataSource, accessibilite?: Colonne): accessibilite is Colonne =>
accessibilite?.colonne != null && source[accessibilite.colonne] != null && source[accessibilite.colonne] !== '';

export const processAccessibilite = (source: DataSource, matching: LieuxMediationNumeriqueMatching): Url | undefined =>
canProcessAccessibilite(source, matching.accessibilite) ? Url(source[matching.accessibilite.colonne] ?? '') : undefined;
export const processAccessibilite = (
source: DataSource,
matching: LieuxMediationNumeriqueMatching,
accesLibreData: Erp[],
adresseProcessed: Adresse
): Url | undefined =>
canProcessAccessibilite(source, matching.accessibilite)
? Url(source[matching.accessibilite.colonne] ?? '')
: getAccessibiliteFromAccesLibre(source, matching, accesLibreData, adresseProcessed);
12 changes: 8 additions & 4 deletions src/transformer/input/to-lieux-mediation-numerique.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '@gouvfr-anct/lieux-de-mediation-numerique';
import { Recorder, Report } from '../report';
import {
Erp,
processAccessibilite,
processAdresse,
processConditionsAcces,
Expand Down Expand Up @@ -73,7 +74,8 @@ const lieuDeMediationNumerique = (
dataSource: DataSource,
sourceName: string,
matching: LieuxMediationNumeriqueMatching,
recorder: Recorder
recorder: Recorder,
accesLibreData: Erp[]
): LieuMediationNumerique => {
const lieuMediationNumerique: LieuMediationNumerique = {
id: processId(dataSource, matching, index),
Expand All @@ -94,7 +96,9 @@ const lieuDeMediationNumerique = (
...horairesIfAny(processHoraires(dataSource, matching)),
...priseRdvIfAny(processPriseRdv(dataSource, matching)),
...typologiesIfAny(processTypologies(dataSource, matching)),
...accessibiliteIfAny(processAccessibilite(dataSource, matching))
...accessibiliteIfAny(
processAccessibilite(dataSource, matching, accesLibreData, processAdresse(recorder)(dataSource, matching))
)
};

recorder.commit();
Expand All @@ -110,10 +114,10 @@ const entryIdentification = (dataSource: DataSource, matching: string): string =
: dataSource[JSON.parse(matching).nom.colonne]) ?? '';

export const toLieuxMediationNumerique =
(matching: string, sourceName: string, report: Report) =>
(matching: string, sourceName: string, report: Report, accesLibreData: Erp[]) =>
(dataSource: DataSource, index: number): LieuMediationNumerique | undefined => {
try {
return lieuDeMediationNumerique(index, dataSource, sourceName, JSON.parse(matching), report.entry(index));
return lieuDeMediationNumerique(index, dataSource, sourceName, JSON.parse(matching), report.entry(index), accesLibreData);
} catch (error: unknown) {
if (
error instanceof ServicesError ||
Expand Down

0 comments on commit db48660

Please sign in to comment.