Skip to content

Commit

Permalink
feat(schema): add modalites acces field
Browse files Browse the repository at this point in the history
  • Loading branch information
abelkhay authored and marc-gavanier committed Apr 16, 2024
1 parent 77cef20 commit a76c065
Show file tree
Hide file tree
Showing 18 changed files with 262 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './url';
export * from './lieu-mediation-numerique';
export * from './model';
export * from './presentation';
export * from './modalite-acces';
2 changes: 2 additions & 0 deletions src/models/lieu-mediation-numerique.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Services } from './service';
import { PublicsAccueillis } from './public-accueilli';
import { ConditionsAcces } from './condition-acces';
import { ModalitesAccompagnement } from './modalite-accompagnement';
import { ModalitesAcces } from './modalite-acces';
import { Url } from './url';
import { Pivot } from './pivot';
import { CleBan } from './cle-ban';
Expand All @@ -34,6 +35,7 @@ export type LieuMediationNumerique = {
services: Services;
publics_accueillis?: PublicsAccueillis;
conditions_acces?: ConditionsAcces;
modalites_acces?: ModalitesAcces;
labels_nationaux?: LabelsNationaux;
labels_autres?: string[];
modalites_accompagnement?: ModalitesAccompagnement;
Expand Down
1 change: 1 addition & 0 deletions src/models/modalite-acces/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './modalite-acces.error';
9 changes: 9 additions & 0 deletions src/models/modalite-acces/errors/modalite-acces.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ModelError } from '../../../errors';
import { LieuMediationNumerique } from '../../lieu-mediation-numerique';
import { ModaliteAcces, ModalitesAccesIndefinie } from '../modalite-acces';

export class ModalitesAccesError extends ModelError<LieuMediationNumerique> {
constructor(modalitesAcces: ModaliteAcces | ModalitesAccesIndefinie) {
super('modalites_acces', `La modalité d'accès '${modalitesAcces}' n'est pas une valeur admise`);
}
}
2 changes: 2 additions & 0 deletions src/models/modalite-acces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './errors';
export * from './modalite-acces';
22 changes: 22 additions & 0 deletions src/models/modalite-acces/modalite-acces.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ModalitesAccesError } from './errors';
import { ModaliteAcces, ModalitesAcces } from './modalite-acces';

describe('modalite acces model', (): void => {
it('should create valid modalites acces', (): void => {
const modalitesAcces: ModalitesAcces = ModalitesAcces([ModaliteAcces.SePresenter]);

expect(modalitesAcces).toStrictEqual([ModaliteAcces.SePresenter]);
});

it('should not create invalid modalites acces', (): void => {
expect((): void => {
ModalitesAcces(['Venir sur place' as ModaliteAcces]);
}).toThrow(new ModalitesAccesError('Venir sur place' as ModaliteAcces));
});

it('should not create invalid modalite acces containing a valid and an invalid value', (): void => {
expect((): void => {
ModalitesAcces([ModaliteAcces.SePresenter, 'Venir sur place' as ModaliteAcces]);
}).toThrow(new ModalitesAccesError('Venir sur place' as ModaliteAcces));
});
});
29 changes: 29 additions & 0 deletions src/models/modalite-acces/modalite-acces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Model } from '../model';
import { ModalitesAccesError } from './errors';

export enum ModaliteAcces {
SePresenter = 'Se présenter',
Telephoner = 'Téléphoner',
ContacterParMail = 'Contacter par mail',
PrescriptionParMail = 'Envoyer un mail avec une fiche de prescription',
PrendreRdvEnLigne = 'Prendre un RDV en ligne',
PasDePublic = "Ce lieu n'accueille pas de public"
}

export type ModalitesAcces = Model<'ModalitesAcces', ModaliteAcces[]>;

export type ModalitesAccesIndefinie = "modalité d'accès indéfinie";

const firstInvalidModaliteAcces = (modaliteAcces: ModaliteAcces): boolean =>
!Object.values(ModaliteAcces).includes(modaliteAcces);

const throwModalitesAccesError = (modalitesAcces: ModaliteAcces[]): ModalitesAcces => {
throw new ModalitesAccesError(modalitesAcces.find(firstInvalidModaliteAcces) ?? "modalité d'accès indéfinie");
};

const isModalitesAcces = (modalitesAcces: ModaliteAcces[]): modalitesAcces is ModalitesAcces =>
modalitesAcces.find(firstInvalidModaliteAcces) == null;

/* eslint-disable-next-line @typescript-eslint/naming-convention */
export const ModalitesAcces = (modalitesAcces: ModaliteAcces[]): ModalitesAcces =>
isModalitesAcces(modalitesAcces) ? modalitesAcces : throwModalitesAccesError(modalitesAcces);
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
LabelNational,
LabelsNationaux,
Localisation,
ModaliteAcces,
ModalitesAcces,
ModaliteAccompagnement,
ModalitesAccompagnement,
/* eslint-disable-next-line @typescript-eslint/no-shadow */
Expand Down Expand Up @@ -48,6 +50,13 @@ export const FRAIS_TO_CONDITION_ACCES: Map<string, ConditionAcces> = new Map<str
['pass-numerique', ConditionAcces.AccepteLePassNumerique]
]);

export const MODES_ORIENTATION_TO_MODALITE_ACCES: Map<string, ModaliteAcces> = new Map<string, ModaliteAcces>([
['se-presenter', ModaliteAcces.SePresenter],
['telephoner', ModaliteAcces.Telephoner],
['envoyer-un-mail', ModaliteAcces.ContacterParMail],
['prise-rdv', ModaliteAcces.PrendreRdvEnLigne]
]);

const LABELS_NATIONAUX_MAP: Map<string, LabelNational> = new Map<string, LabelNational>([
['aidants-connect', LabelNational.AidantsConnect],
['aptic', LabelNational.APTIC],
Expand Down Expand Up @@ -228,12 +237,35 @@ export const modalitesAccompagnementFromDataInclusion = (
types
.map((type: string): ModaliteAccompagnement | undefined => TYPES_TO_MODALITES_ACCOMPAGNEMENT_MAP.get(type))
.filter(
(modalitesAccompagnement?: ModaliteAccompagnement): modalitesAccompagnement is ModaliteAccompagnement =>
modalitesAccompagnement != null
(modaliteAccompagnement?: ModaliteAccompagnement): modaliteAccompagnement is ModaliteAccompagnement =>
modaliteAccompagnement != null
)
)
};

const defaultModalitesAcces = (priseRdv?: { prise_rdv?: Url }): ModaliteAcces[] =>
priseRdv?.prise_rdv == null ? [] : [ModaliteAcces.PrendreRdvEnLigne];

const onlyDefined = <T>(nullable?: T): nullable is T => nullable != null;

const toModaliteAccess = (modeOrientation: string): ModaliteAcces | undefined =>
MODES_ORIENTATION_TO_MODALITE_ACCES.get(modeOrientation);

const hasModesOrientation = (modesOrientation?: string[]): modesOrientation is string[] =>
modesOrientation != null && modesOrientation.length > 0;

export const modalitesAccesFromDataInclusion = (
modesOrientation?: string[],
priseRdv?: { prise_rdv?: Url }
): { modalites_acces?: ModalitesAcces } => ({
modalites_acces: ModalitesAcces([
...defaultModalitesAcces(priseRdv),
...(hasModesOrientation(modesOrientation)
? modesOrientation.map(toModaliteAccess).filter(onlyDefined)
: [ModaliteAcces.SePresenter, ModaliteAcces.Telephoner, ModaliteAcces.ContacterParMail])
])
});

export const presentationFromDataInclusion = (
presentation_detail?: string,
presentation_resume?: string
Expand Down Expand Up @@ -295,3 +327,10 @@ export const mergeFrais = (frais?: string[], fraisToAdd?: string[]): { frais?: s

export const mergePriseRdv = (priseRdv?: string, priseRdvToAdd?: string): { prise_rdv?: string } =>
priseRdv == null && priseRdvToAdd == null ? {} : { prise_rdv: priseRdvToAdd ?? priseRdv ?? '' };

export const mergeModesOrientation = (
modesOrientation?: string[],
modesOrientationToAdd?: string[]
): { modes_orientation: string[] } => ({
modes_orientation: Array.from(new Set([...(modesOrientation ?? []), ...(modesOrientationToAdd ?? [])]))
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
LabelsNationaux,
LieuMediationNumerique,
Localisation,
ModaliteAcces,
ModaliteAccompagnement,
ModalitesAcces,
ModalitesAccompagnement,
Nom,
Pivot,
Expand Down Expand Up @@ -59,6 +61,7 @@ describe('from schema data inclusion', (): void => {
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives]),
modalites_acces: ModalitesAcces([ModaliteAcces.SePresenter, ModaliteAcces.Telephoner, ModaliteAcces.ContacterParMail]),
date_maj: new Date('2022-10-10')
});
});
Expand Down Expand Up @@ -162,6 +165,12 @@ describe('from schema data inclusion', (): void => {
Service.PromouvoirLaCitoyenneteNumerique,
Service.SoutenirLaParentalite
]),
modalites_acces: ModalitesAcces([
ModaliteAcces.PrendreRdvEnLigne,
ModaliteAcces.SePresenter,
ModaliteAcces.Telephoner,
ModaliteAcces.ContacterParMail
]),
date_maj: new Date('2022-10-10'),
localisation: Localisation({
latitude: 43.52609,
Expand Down Expand Up @@ -286,6 +295,7 @@ describe('from schema data inclusion', (): void => {
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives]),
modalites_acces: ModalitesAcces([ModaliteAcces.SePresenter, ModaliteAcces.Telephoner, ModaliteAcces.ContacterParMail]),
date_maj: new Date('2022-10-10')
});
});
Expand Down Expand Up @@ -323,6 +333,7 @@ describe('from schema data inclusion', (): void => {
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives]),
modalites_acces: ModalitesAcces([ModaliteAcces.SePresenter, ModaliteAcces.Telephoner, ModaliteAcces.ContacterParMail]),
date_maj: new Date('2022-10-10')
});
});
Expand Down Expand Up @@ -382,6 +393,7 @@ describe('from schema data inclusion', (): void => {
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives, Service.AccederAUneConnexionInternet]),
modalites_acces: ModalitesAcces([ModaliteAcces.SePresenter, ModaliteAcces.Telephoner, ModaliteAcces.ContacterParMail]),
date_maj: new Date('2022-10-10')
});
});
Expand Down Expand Up @@ -427,6 +439,7 @@ describe('from schema data inclusion', (): void => {
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives, Service.AccederAUneConnexionInternet]),
modalites_acces: ModalitesAcces([ModaliteAcces.SePresenter, ModaliteAcces.Telephoner, ModaliteAcces.ContacterParMail]),
date_maj: new Date('2022-10-10'),
conditions_acces: ConditionsAcces([ConditionAcces.Payant, ConditionAcces.Gratuit])
});
Expand Down Expand Up @@ -490,6 +503,12 @@ describe('from schema data inclusion', (): void => {
Service.PrendreEnMainUnSmartphoneOuUneTablette,
Service.PrendreEnMainUnOrdinateur
]),
modalites_acces: ModalitesAcces([
ModaliteAcces.PrendreRdvEnLigne,
ModaliteAcces.SePresenter,
ModaliteAcces.Telephoner,
ModaliteAcces.ContacterParMail
]),
date_maj: new Date('2022-10-10'),
publics_accueillis: PublicsAccueillis([
PublicAccueilli.Seniors,
Expand All @@ -506,4 +525,86 @@ describe('from schema data inclusion', (): void => {
prise_rdv: Url('https://www.rdv-solidarites.fr/service2')
});
});

it('should get modalite acces with prise rdv', (): void => {
const structure: SchemaStructureDataInclusion = {
adresse: '12 BIS RUE DE LECLERCQ',
code_postal: '51100',
commune: 'Reims',
date_maj: new Date('2022-10-10').toISOString(),
id: 'structure-1',
nom: 'Anonymal',
siret: '43493312300029'
};

const service: SchemaServiceDataInclusion = {
id: 'structure-1-mediation-numerique',
nom: 'Médiation numérique',
source: 'Hubik',
structure_id: 'structure-1',
thematiques: ['numerique--devenir-autonome-dans-les-demarches-administratives'],
modes_orientation: ['se-presenter'],
prise_rdv: 'http://www.test.com'
};

const minimalLieuMediationNumerique: LieuMediationNumerique = fromSchemaDataInclusion([service], structure);

expect(minimalLieuMediationNumerique).toStrictEqual<LieuMediationNumerique>({
id: Id('structure-1'),
nom: Nom('Anonymal'),
pivot: Pivot('43493312300029'),
adresse: Adresse({
code_postal: '51100',
commune: 'Reims',
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives]),
date_maj: new Date('2022-10-10'),
modalites_acces: ModalitesAcces([ModaliteAcces.PrendreRdvEnLigne, ModaliteAcces.SePresenter]),
prise_rdv: Url('http://www.test.com')
});
});

it('should get defaut modalites when no modes orientation from data inclusion', (): void => {
const structure: SchemaStructureDataInclusion = {
adresse: '12 BIS RUE DE LECLERCQ',
code_postal: '51100',
commune: 'Reims',
date_maj: new Date('2022-10-10').toISOString(),
id: 'structure-1',
nom: 'Anonymal',
siret: '43493312300029'
};

const service: SchemaServiceDataInclusion = {
id: 'structure-1-mediation-numerique',
nom: 'Médiation numérique',
source: 'Hubik',
structure_id: 'structure-1',
thematiques: ['numerique--devenir-autonome-dans-les-demarches-administratives'],
prise_rdv: 'http://www.test.com'
};

const minimalLieuMediationNumerique: LieuMediationNumerique = fromSchemaDataInclusion([service], structure);

expect(minimalLieuMediationNumerique).toStrictEqual<LieuMediationNumerique>({
id: Id('structure-1'),
nom: Nom('Anonymal'),
pivot: Pivot('43493312300029'),
adresse: Adresse({
code_postal: '51100',
commune: 'Reims',
voie: '12 BIS RUE DE LECLERCQ'
}),
services: Services([Service.DevenirAutonomeDansLesDemarchesAdministratives]),
date_maj: new Date('2022-10-10'),
modalites_acces: ModalitesAcces([
ModaliteAcces.PrendreRdvEnLigne,
ModaliteAcces.SePresenter,
ModaliteAcces.Telephoner,
ModaliteAcces.ContacterParMail
]),
prise_rdv: Url('http://www.test.com')
});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention, camelcase */
/* eslint-disable @typescript-eslint/naming-convention, camelcase, max-lines-per-function */

import { Id, LieuMediationNumerique, Nom, Pivot } from '../../../models';
import { SchemaServiceDataInclusion, SchemaStructureDataInclusion } from '../schema-data-inclusion';
Expand All @@ -11,10 +11,12 @@ import {
labelsFromDataInclusion,
localisationFromDataInclusion,
mergeFrais,
mergeModesOrientation,
mergePriseRdv,
mergeProfils,
mergeThematiques,
mergeTypes,
modalitesAccesFromDataInclusion,
modalitesAccompagnementFromDataInclusion,
presentationFromDataInclusion,
priseRdvFromDataInclusion,
Expand All @@ -36,7 +38,8 @@ const toSingleService = (
...mergeFrais(mergedService.frais, service.frais),
...mergeProfils(mergedService.profils, service.profils),
...mergeTypes(mergedService.types, service.types),
...mergePriseRdv(mergedService.prise_rdv, service.prise_rdv)
...mergePriseRdv(mergedService.prise_rdv, service.prise_rdv),
...mergeModesOrientation(mergedService.modes_orientation, service.modes_orientation)
});

export const mergeServices = (
Expand Down Expand Up @@ -73,6 +76,7 @@ const fromSchemaDataInclusionItem = (
...horairesFromDataInclusion(structure.horaires_ouverture),
...labelsFromDataInclusion(structure.labels_nationaux, structure.labels_autres),
...modalitesAccompagnementFromDataInclusion(service.types),
...modalitesAccesFromDataInclusion(service.modes_orientation, priseRdvFromDataInclusion(service.prise_rdv)),
...presentationFromDataInclusion(structure.presentation_detail, structure.presentation_resume),
...priseRdvFromDataInclusion(service.prise_rdv),
...publicsAccueillisFromDataInclusion(service.profils),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export type SchemaStructureDataInclusionCollecteFields = {
export type SchemaStructureDataInclusionAccesFields = {
profils?: string[];
frais?: string[];
modes_orientation?: string[];
types?: string[];
};

Expand Down
Loading

0 comments on commit a76c065

Please sign in to comment.