diff --git a/scripts/data/structures.js b/scripts/data/structures.js index 0a3df8be0ca3ede30a3aff62c01a993a4563524e..72de0768adcd26c62562c8bd701b4135aac2a319 100644 --- a/scripts/data/structures.js +++ b/scripts/data/structures.js @@ -140,6 +140,7 @@ module.exports = { numero: '18', street: 'Rue de la Mairie', commune: 'Feyzin', + postcode: '69320', }, accountVerified: true, coord: [4.8563106, 45.6693619], @@ -256,6 +257,7 @@ module.exports = { numero: '27', street: 'Avenue de la République', commune: 'Vénissieux', + postcode: '69259', }, accountVerified: true, coord: [4.8678548, 45.7075853], @@ -302,6 +304,7 @@ module.exports = { numero: '7', street: 'Rue Saint Polycarpe', commune: 'Lyon 1er', + postcode: '69001', }, hours: { monday: { @@ -462,6 +465,7 @@ module.exports = { numero: '30 bis', street: 'Avenue Leclerc', commune: 'Rillieux-la-Pape', + postcode: '69286', }, coord: [4.9036773, 45.8142196], accountVerified: true, @@ -585,6 +589,7 @@ module.exports = { numero: '212', street: 'Avenue Franklin Roosevelt', commune: 'Bron', + postcode: '69500', }, coord: [4.9149121, 45.7311648], accountVerified: true, @@ -687,6 +692,7 @@ module.exports = { numero: '3', street: 'Rue Louis Normand', commune: 'Oullins', + postcode: '69600', }, coord: [4.8188378, 45.7157896], accountVerified: true, @@ -797,6 +803,7 @@ module.exports = { numero: '7', street: 'Rue Robert et Reynier ', commune: 'Saint-Fons', + postcode: '69199', }, coord: [4.8608585, 45.7086482], accountVerified: true, @@ -872,6 +879,7 @@ module.exports = { numero: '172', street: 'Avenue Général Frère', commune: 'Lyon 8e', + postcode: '69008', }, createdAt: '2020-11-13T14:13:00.000Z', updatedAt: '2022-04-13T14:13:00.000Z', @@ -939,6 +947,7 @@ module.exports = { numero: '2', street: 'Rue Neuve', commune: 'Fleurieu-sur-Saône', + postcode: '69250', }, createdAt: '2022-01-13T14:13:00.000Z', updatedAt: '2022-02-13T14:13:00.000Z', diff --git a/src/migrations/scripts/1669632514462-add-postcode.ts b/src/migrations/scripts/1669632514462-add-postcode.ts new file mode 100644 index 0000000000000000000000000000000000000000..86cac17417c2b645566fb6f7d63988c8e15d74bd --- /dev/null +++ b/src/migrations/scripts/1669632514462-add-postcode.ts @@ -0,0 +1,38 @@ +import { Db } from 'mongodb'; +import { getDb } from '../migrations-utils/db'; +import { HttpService } from '@nestjs/axios'; +import { lastValueFrom } from 'rxjs'; + +export const up = async () => { + const db: Db = await getDb(); + const cursor = db.collection('structures').find({}); + let document; + while ((document = await cursor.next())) { + const newDoc = document; + const httpService = new HttpService(); + await lastValueFrom( + httpService.get( + encodeURI( + `https://download.data.grandlyon.com/geocoding/photon/api?q=${document.address.commune}&lang=fr&limit=1` + ) + ) + ).then(async (res) => { + newDoc.address.postcode = res.data.features[0].properties.postcode; + await db.collection('structures').updateOne({ _id: document._id }, [{ $set: newDoc }]); + console.log( + `${document.structureName}, ${document.address.commune} : ${res.data.features[0].properties.postcode}` + ); + }); + } + console.log('Update done : postcodes added to structures'); +}; + +export const down = async () => { + const db: Db = await getDb(); + const cursor = db.collection('structures').find({}); + let document; + while ((document = await cursor.next())) { + await db.collection('structures').updateOne({ _id: document._id }, [{ $unset: 'address.postcode' }]); + } + console.log(`Downgrade done : postcodes removed from structures`); +}; diff --git a/src/structures/schemas/address.schema.ts b/src/structures/schemas/address.schema.ts index 8fa4e35c5c469dcfd2a36d88b78faf7d1575a93f..7e822db4c5eb894d595701ec1ab6afb998bcce29 100644 --- a/src/structures/schemas/address.schema.ts +++ b/src/structures/schemas/address.schema.ts @@ -11,6 +11,8 @@ export class Address { @IsNotEmpty() commune: string; + + postcode: string; } export const AddressSchema = SchemaFactory.createForClass(Address); diff --git a/src/structures/services/aptic-structures.service.ts b/src/structures/services/aptic-structures.service.ts index 36c1ac841897dbfa41d1e980fc4a4ff2777d49c2..eddf09fa36f3b8959088b84008d87da2ffa59a54 100644 --- a/src/structures/services/aptic-structures.service.ts +++ b/src/structures/services/aptic-structures.service.ts @@ -304,6 +304,7 @@ export class ApticStructuresService { } address.commune = this.structureService.getFormattedCity(structure.address.city, structure.address.zip); + address.postcode = structure.address.zip; return address; } } diff --git a/src/structures/services/structures-search.service.ts b/src/structures/services/structures-search.service.ts index b29d1fb66b32dcc142c040cbdf9bb9df4360a236..d11f7787d337092d929a05d2a4b8861cd2377dab 100644 --- a/src/structures/services/structures-search.service.ts +++ b/src/structures/services/structures-search.service.ts @@ -97,14 +97,18 @@ export class StructuresSearchService { searchString = searchString ? searchString + '*' : '*'; const { hits } = await this.elasticsearchService.search<StructureSearchBody>({ index: this.index, - from: 0, - size: 500, - query: { - query_string: { - analyze_wildcard: true, - query: searchString, - fields: fields ? fields : ['structureName^5', 'structureType^5', 'address.commune^10', 'description'], - fuzziness: 'AUTO', + body: { + from: 0, + size: 500, + query: { + query_string: { + analyze_wildcard: true, + query: searchString, + fields: fields + ? fields + : ['structureName^5', 'structureType^5', 'address.commune^10', 'address.postcode^5', 'description'], + fuzziness: 'AUTO', + }, }, }, }); diff --git a/src/structures/services/structures.service.spec.ts b/src/structures/services/structures.service.spec.ts index 60b44236ed2b861e2938751d015906fc189bfd27..e638eca20b335edd8cf9e36189c27d1e8d527065 100644 --- a/src/structures/services/structures.service.spec.ts +++ b/src/structures/services/structures.service.spec.ts @@ -159,6 +159,7 @@ const structuresSearchServiceMock = { numero: '30 bis', street: 'Avenue Leclerc', commune: 'Rillieux-la-Pape', + postcode: '69250', }, coord: [4.9036773, 45.8142196], accountVerified: true, @@ -349,6 +350,7 @@ describe('StructuresService', () => { numero: '30 bis', street: 'Avenue Leclerc', commune: 'Rillieux-la-Pape', + postcode: '69250', }, coord: [4.9036773, 45.8142196], accountVerified: true, diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts index f562724d6213ba43d1fea6b79bd5cf2db5013d28..e458a70bd521cbffb1d4b4e37cd8079da2fd286a 100644 --- a/src/structures/services/structures.service.ts +++ b/src/structures/services/structures.service.ts @@ -144,10 +144,14 @@ export class StructuresService { await this.getStructurePosition(createdStructure).then(async (position: StructureDocument) => { return this.structuresSearchService.indexStructure( await this.structureModel - .findByIdAndUpdate(new Types.ObjectId(createdStructure._id), { - address: position.address, - coord: position.coord, - }) + .findByIdAndUpdate( + new Types.ObjectId(createdStructure._id), + { + address: position.address, + coord: position.coord, + }, + { new: true } + ) .populate('personalOffers') .populate('structureType') .exec() @@ -433,6 +437,7 @@ export class StructuresService { const address = resbal.data.features[0]; if (address && address.geometry) { structure.coord = address.geometry.coordinates; + structure.address.postcode = address.properties.postcode; } else { this.logger.error( `No coord found for: ${structure.address.numero} ${structure.address.street} ${structure.address.commune}`, @@ -447,6 +452,7 @@ export class StructuresService { const address = res.data.features[0]; if (address && address.geometry) { structure.coord = address.geometry.coordinates; + structure.address.postcode = address.properties.postcode; } else { this.logger.error( `No coord found for: ${structure.address.numero} ${structure.address.street} ${structure.address.commune}`, @@ -600,12 +606,16 @@ export class StructuresService { public getCoord( numero: string, address: string, - zipcode: string, + commune: string, scope: string ): Observable<AxiosResponse<PhotonResponse>> { const req = - `https://download.data.grandlyon.com/geocoding/${scope}/api?q=` + numero + ' ' + address + ' ' + zipcode; - this.logger.debug('Print getCoord' + req); + `https://download.data.grandlyon.com/geocoding/${scope}/api?q=` + + (numero == null ? '' : numero + ' ') + + address + + ' ' + + commune; + this.logger.debug('Print getCoord ' + req); return this.httpService.get(encodeURI(req)); } diff --git a/src/structures/structures.controller.ts b/src/structures/structures.controller.ts index 2155605ff7fa740153408516b57b5ee73e32b4bd..8749f1d07726bd3e7b33c6175e9b9f058c2d1833 100644 --- a/src/structures/structures.controller.ts +++ b/src/structures/structures.controller.ts @@ -65,7 +65,8 @@ export class StructuresController { .then((data) => data.filter( (cityPoint) => - cityPoint.properties.city?.toLowerCase().includes(city.toLowerCase()) && + (cityPoint.properties.postcode == city || + cityPoint.properties.city?.toLowerCase().includes(city.toLowerCase())) && cityPoint.properties.postcode.match(depRegex) ) ) diff --git a/test/mock/data/structures.mock.data.ts b/test/mock/data/structures.mock.data.ts index 03cce1b4f354b59ee5cc18a503d113b275ea2bd6..bbd943cacbdfbf9954367c9c4bb28b70f6ffc119 100644 --- a/test/mock/data/structures.mock.data.ts +++ b/test/mock/data/structures.mock.data.ts @@ -18,6 +18,7 @@ export const structuresDocumentDataMock: StructureDocument[] = [ numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -93,6 +94,7 @@ export const structuresDocumentDataMock: StructureDocument[] = [ numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -176,6 +178,7 @@ export const structureMockDto: StructureDto = { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', diff --git a/test/mock/services/structures-for-search.mock.service.ts b/test/mock/services/structures-for-search.mock.service.ts index 2e8e04feb4cf11427e59a77889b213874c0fef09..816f18da0fa1e046995b76ee610ed364ed5f99af 100644 --- a/test/mock/services/structures-for-search.mock.service.ts +++ b/test/mock/services/structures-for-search.mock.service.ts @@ -9,6 +9,7 @@ export class StructuresForSearchServiceMock { numero: '1', street: 'Avenue Edouard Aynard', commune: 'Écully', + postcode: '69130', }, nbPrinters: 1, description: @@ -22,6 +23,7 @@ export class StructuresForSearchServiceMock { numero: null, street: " Place de l'Abbe Launay", commune: 'Grézieu-la-Varenne', + postcode: '69290', }, nbPrinters: 1, description: null, @@ -34,6 +36,7 @@ export class StructuresForSearchServiceMock { numero: null, street: 'Place de la Mairie', commune: 'La Tour-de-Salvagny', + postcode: '69890', }, nbPrinters: 1, description: null, @@ -46,6 +49,7 @@ export class StructuresForSearchServiceMock { numero: '10', street: 'Chemin Jean-Marie Vianney', commune: 'Écully', + postcode: '69130', }, nbPrinters: 1, description: null, @@ -58,6 +62,7 @@ export class StructuresForSearchServiceMock { numero: '17', street: 'Rue Tupin', commune: 'Oullins', + postcode: '69600', }, description: null, nbPrinters: 1, @@ -71,6 +76,7 @@ export class StructuresForSearchServiceMock { numero: '7', street: 'Rue Robert et Reynier ', commune: 'Saint-Fons', + postcode: '69199', }, nbScanners: 1, description: @@ -84,6 +90,7 @@ export class StructuresForSearchServiceMock { numero: '37', street: 'a Rue du Mai 1945', commune: 'Villeurbanne', + postcode: '69100', }, nbScanners: 1, description: "Notre rôle est de faciliter l'accès des personnes aux services nécessaires à la vie quotidienne", diff --git a/test/mock/services/structures.mock.service.ts b/test/mock/services/structures.mock.service.ts index bb7bb9e891a0ea94b7f4081f4b015964ec73b452..d93d40d6c623231537dde474bfcf2b5fa6fbbcfe 100644 --- a/test/mock/services/structures.mock.service.ts +++ b/test/mock/services/structures.mock.service.ts @@ -56,6 +56,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -247,6 +248,7 @@ export class StructuresServiceMock { numero: '30 bis', street: 'Avenue Leclerc', commune: 'Rillieux-la-Pape', + postcode: '69286', }, coord: [4.9036773, 45.8142196], accountVerified: true, @@ -400,6 +402,7 @@ export class StructuresServiceMock { numero: '30 bis', street: 'Avenue Leclerc', commune: 'Rillieux-la-Pape', + postcode: '69286', }, coord: [4.9036773, 45.8142196], accountVerified: true, @@ -465,6 +468,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -565,6 +569,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -670,6 +675,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -770,6 +776,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -875,6 +882,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -978,6 +986,7 @@ export class StructuresServiceMock { street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', }, + postcode: '69007', contactMail: '', contactPhone: '', website: '', @@ -1054,6 +1063,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -1166,6 +1176,7 @@ export class StructuresServiceMock { numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, contactMail: '', contactPhone: '', @@ -1373,6 +1384,7 @@ export const mockResinStructures: Array<Structure> = [ numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, website: '', facebook: null, @@ -1476,6 +1488,7 @@ export const mockResinStructures: Array<Structure> = [ numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, website: '', facebook: null, @@ -1579,6 +1592,7 @@ export const mockResinStructures: Array<Structure> = [ numero: null, street: 'Rue Alphonse Daudet', commune: 'Lyon 7ème Arrondissement', + postcode: '69007', }, website: '', facebook: null,