From 87ca7411ca6a61c5e23319fa472f8dff10627c8c Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Thu, 26 Nov 2020 08:53:27 +0100
Subject: [PATCH] feat: update readme + make coord and address call in backend
 instead of front

---
 README.md                                  | 41 ++++++++++++----
 src/structures/schemas/structure.schema.ts |  6 +++
 src/structures/structures.module.ts        |  4 +-
 src/structures/structures.service.ts       | 56 ++++++++++++++++++++--
 4 files changed, 94 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md
index 77f2c9d72..5edb496c7 100644
--- a/README.md
+++ b/README.md
@@ -24,16 +24,37 @@
 
 ## Description
 
-[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
+L'appplication est basée sur le framework [Nest](https://github.com/nestjs/nest). Celle-ci utilise une BDD mongodb.
 
 ## Installation
 
+### Prérequis
+
+Windows: avoir Docker Desktop installé
+Linux: avoir docker et docker-compose installé
+
+Créer un ficher .env sur le modèle du ficher `template.env` et remplir les différentes variables.
+
+### Application
+
+Installation des dépendences applicatives:
+
 ```bash
 $ npm install
 ```
 
 ## Running the app
 
+### Base de donnée
+
+
+```bash
+$ docker-compose up -d database-ram
+$ docker-compose up -d mongo-express
+```
+
+### Application
+
 ```bash
 # development
 $ npm run start
@@ -45,6 +66,16 @@ $ npm run start:dev
 $ npm run start:prod
 ```
 
+### Infos
+
+```bash
+# Lien vers le swagger
+$ http://localhost:3000/api
+
+# Lien vers le mongo-express
+$ http://localhost:8081
+```
+
 ## Test
 
 ```bash
@@ -62,12 +93,6 @@ $ npm run test:cov
 
 Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
 
-## Stay in touch
-
-- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
-- Website - [https://nestjs.com](https://nestjs.com/)
-- Twitter - [@nestframework](https://twitter.com/nestframework)
-
 ## License
 
-  Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
+Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
diff --git a/src/structures/schemas/structure.schema.ts b/src/structures/schemas/structure.schema.ts
index aaebe759f..821547e9f 100644
--- a/src/structures/schemas/structure.schema.ts
+++ b/src/structures/schemas/structure.schema.ts
@@ -39,6 +39,9 @@ export class Structure {
   @Prop()
   voie: string;
 
+  @Prop()
+  address: string;
+
   @Prop()
   telephone: string;
 
@@ -158,6 +161,9 @@ export class Structure {
 
   @Prop()
   hours: Week;
+
+  @Prop()
+  coord: number[];
 }
 
 export const StructureSchema = SchemaFactory.createForClass(Structure);
diff --git a/src/structures/structures.module.ts b/src/structures/structures.module.ts
index 555c9dd7b..f6843d41b 100644
--- a/src/structures/structures.module.ts
+++ b/src/structures/structures.module.ts
@@ -1,11 +1,11 @@
-import { Module } from '@nestjs/common';
+import { HttpModule, Module } from '@nestjs/common';
 import { MongooseModule } from '@nestjs/mongoose';
 import { Structure, StructureSchema } from './schemas/structure.schema';
 import { StructuresController } from './structures.controller';
 import { StructuresService } from './structures.service';
 
 @Module({
-  imports: [MongooseModule.forFeature([{ name: Structure.name, schema: StructureSchema }])],
+  imports: [MongooseModule.forFeature([{ name: Structure.name, schema: StructureSchema }]), HttpModule],
   controllers: [StructuresController],
   providers: [StructuresService],
 })
diff --git a/src/structures/structures.service.ts b/src/structures/structures.service.ts
index f3a67fda7..477324a4d 100644
--- a/src/structures/structures.service.ts
+++ b/src/structures/structures.service.ts
@@ -1,13 +1,18 @@
-import { Injectable } from '@nestjs/common';
+import { HttpService, Injectable } from '@nestjs/common';
 import { InjectModel } from '@nestjs/mongoose';
 import { Model } from 'mongoose';
+import { Observable } from 'rxjs';
+import { AxiosResponse } from 'axios';
 import { CreateStructureDto } from './dto/create-structure.dto';
-import { Filter } from './schemas/filter.schema';
 import { Structure, StructureDocument } from './schemas/structure.schema';
+import { Logger } from '@nestjs/common';
 
 @Injectable()
 export class StructuresService {
-  constructor(@InjectModel(Structure.name) private structureModel: Model<StructureDocument>) {}
+  constructor(
+    private readonly httpService: HttpService,
+    @InjectModel(Structure.name) private structureModel: Model<StructureDocument>
+  ) {}
 
   public async create(createStructrureDto: CreateStructureDto): Promise<Structure> {
     const createdStructure = new this.structureModel(createStructrureDto);
@@ -42,9 +47,47 @@ export class StructuresService {
   }
 
   public async findAll(): Promise<Structure[]> {
+    const structures = await this.structureModel.find().exec();
+    // Update structures coord and address before sending them
+    await Promise.all(
+      structures.map((structure: Structure) => {
+        // If structre has no address, add it
+        if (!structure.address) {
+          this.getStructurePosition(structure).then((postition) => {
+            this.structureModel
+              .findOneAndUpdate({ id: structure.id }, { address: postition.address, coord: postition.coord })
+              .exec();
+          });
+        }
+        if (structure.coord.length <= 0) {
+          this.getStructurePosition(structure).then((postition) => {
+            this.structureModel.findOneAndUpdate({ id: postition.id }, { coord: postition.coord }).exec();
+          });
+        }
+      })
+    );
     return this.structureModel.find().exec();
   }
 
+  /**
+   * Get structures positions and add marker corresponding to those positons on the map
+   */
+  private getStructurePosition(structure: Structure): Promise<Structure> {
+    return new Promise((resolve) => {
+      this.getCoord(structure.n, structure.voie, structure.commune).subscribe(
+        (res) => {
+          const address = res.data.features[0];
+          structure.address = structure.voie + ' - ' + address.properties.postcode + ' ' + address.properties.city;
+          structure.coord = address.geometry.coordinates;
+          resolve(structure);
+        },
+        (err) => {
+          Logger.error(`[getCoord] Request error: ${err.config.url}`, err);
+        }
+      );
+    });
+  }
+
   /**
    * Count every value occurence of a given key
    * @param key structure key
@@ -65,4 +108,11 @@ export class StructuresService {
   public async countByEquipmentsKey(key: string, displayKey: string): Promise<any> {
     return [{ id: displayKey, count: await this.structureModel.countDocuments({ [key]: true }).exec() }];
   }
+
+  public getCoord(numero: string, address: string, zipcode: string): Observable<AxiosResponse<any>> {
+    const req =
+      'https://download.data.grandlyon.com/geocoding/photon/api' + '?q=' + numero + ' ' + address + ' ' + zipcode;
+    Logger.log(`[StructureService - getCoord] Request : ${req}`);
+    return this.httpService.get(encodeURI(req));
+  }
 }
-- 
GitLab