From 509f30f9a2c36b18ed093d25fa37c3b9b3849165 Mon Sep 17 00:00:00 2001
From: Antonin COQUET <ext.sopra.acoquet@grandlyon.com>
Date: Mon, 26 Apr 2021 16:29:25 +0200
Subject: [PATCH] feat: add new endpoint for structures, data is formated
 (jointure on modules)

---
 src/admin/admin.controller.spec.ts            | 26 +++--
 src/app.module.ts                             |  2 +-
 src/categories/categories.module.ts           |  7 +-
 .../1617962328658-add-newsletter-data.ts      | 17 ----
 src/structures/services/structures.service.ts | 98 +++++++++++++++++++
 src/structures/structures.controller.ts       | 16 ++-
 src/users/users.controller.spec.ts            |  1 +
 7 files changed, 140 insertions(+), 27 deletions(-)
 delete mode 100644 src/migrations/scripts/1617962328658-add-newsletter-data.ts

diff --git a/src/admin/admin.controller.spec.ts b/src/admin/admin.controller.spec.ts
index 84dbf424a..153f13440 100644
--- a/src/admin/admin.controller.spec.ts
+++ b/src/admin/admin.controller.spec.ts
@@ -1,4 +1,4 @@
-import { HttpException, HttpModule, HttpStatus } from '@nestjs/common';
+import { HttpModule } from '@nestjs/common';
 import { getModelToken } from '@nestjs/mongoose';
 import { Test, TestingModule } from '@nestjs/testing';
 import { ConfigurationModule } from '../configuration/configuration.module';
@@ -47,21 +47,35 @@ describe('AdminController', () => {
   });
 
   it('should get pending attachments', async () => {
-    const result = [{name: "MJC Route de vienne", address: "14 chemin des platanes"}, {name: "Mairie Lyon 7eme", address: "21 boulevard martin"}];
+    const result = [
+      { name: 'MJC Route de vienne', address: '14 chemin des platanes' },
+      { name: 'Mairie Lyon 7eme', address: '21 boulevard martin' },
+    ];
     jest.spyOn(controller, 'getPendingAttachments').mockImplementation(async (): Promise<any> => result);
     expect(await controller.getPendingAttachments()).toBe(result);
   });
 
   it('should validate pending structure', async () => {
-    const result = [{name: "MJC Route de vienne", address: "14 chemin des platanes"}];
-    const structure: PendingStructureDto = {userEmail:"martin@mjc.fr", structureId: "1", structureName:"MJC Route de vienne"};
+    const result = [{ name: 'MJC Route de vienne', address: '14 chemin des platanes' }];
+    const structure: PendingStructureDto = {
+      userEmail: 'martin@mjc.fr',
+      structureId: '1',
+      structureName: 'MJC Route de vienne',
+    };
     jest.spyOn(controller, 'validatePendingStructure').mockImplementation(async (): Promise<any> => result);
     expect(await controller.validatePendingStructure(structure)).toBe(result);
   });
 
   it('should refuse pending structure', async () => {
-    const result = [{name: "MJC Route de vienne", address: "14 chemin des platanes"}, {name: "Mairie Lyon 7eme", address: "21 boulevard martin"}];
-    const structure: PendingStructureDto = {userEmail:"martin@mjc.fr", structureId: "1", structureName:"MJC Route de vienne"};
+    const result = [
+      { name: 'MJC Route de vienne', address: '14 chemin des platanes' },
+      { name: 'Mairie Lyon 7eme', address: '21 boulevard martin' },
+    ];
+    const structure: PendingStructureDto = {
+      userEmail: 'martin@mjc.fr',
+      structureId: '1',
+      structureName: 'MJC Route de vienne',
+    };
     jest.spyOn(controller, 'refusePendingStructure').mockImplementation(async (): Promise<any> => result);
     expect(await controller.refusePendingStructure(structure)).toBe(result);
   });
diff --git a/src/app.module.ts b/src/app.module.ts
index ed6a03004..3cd15b2b2 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -29,7 +29,7 @@ import { NewsletterModule } from './newsletter/newsletter.module';
     AdminModule,
     PostsModule,
     TempUserModule,
-    NewsletterModule
+    NewsletterModule,
   ],
   controllers: [AppController],
 })
diff --git a/src/categories/categories.module.ts b/src/categories/categories.module.ts
index bc6f3c868..3373d355f 100644
--- a/src/categories/categories.module.ts
+++ b/src/categories/categories.module.ts
@@ -19,7 +19,10 @@ import { CategoriesAccompagnement, CategoriesAccompagnementSchema } from './sche
     ]),
   ],
   controllers: [CategoriesFormationsController, CategoriesAccompagnementController, CategoriesOthersController],
-  exports: [CategoriesFormationsService],
+  exports: [CategoriesFormationsService, CategoriesAccompagnementService, CategoriesOthersService],
   providers: [CategoriesFormationsService, CategoriesAccompagnementService, CategoriesOthersService],
 })
-export class CategoriesModule {}
+export class CategoriesModule {
+  id: string;
+  text: any;
+}
diff --git a/src/migrations/scripts/1617962328658-add-newsletter-data.ts b/src/migrations/scripts/1617962328658-add-newsletter-data.ts
deleted file mode 100644
index 17821b927..000000000
--- a/src/migrations/scripts/1617962328658-add-newsletter-data.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Db } from 'mongodb';
-import { getDb } from '../migrations-utils/db';
-import * as fs from 'fs';
-
-export const up = async () => {
-  const db: Db = await getDb();
-  const data = fs.readFileSync('/app/src/migrations/data/newsletter-data.json', 'utf8');
-  const parsedData = JSON.parse(data);
-  db.collection('newslettersubscriptions').insertMany(parsedData);
-};
-
-export const down = async () => {
-  const db: Db = await getDb();
-  /*
-      Code you downgrade script here!
-   */
-};
diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts
index a1c20918b..c6c02b27a 100644
--- a/src/structures/services/structures.service.ts
+++ b/src/structures/services/structures.service.ts
@@ -14,6 +14,11 @@ import { DateTime } from 'luxon';
 import { IUser } from '../../users/interfaces/user.interface';
 import * as _ from 'lodash';
 import { OwnerDto } from '../../users/dto/owner.dto';
+import { CategoriesFormationsModule } from '../../categories/schemas/categoriesFormationsModule.schema';
+import { CategoriesModule } from '../../categories/categories.module';
+import { CategoriesAccompagnement } from '../../categories/schemas/categoriesAccompagnement.schema';
+import { CategoriesFormations } from '../../categories/schemas/categoriesFormations.schema';
+import { CategoriesOthers } from '../../categories/schemas/categoriesOthers.schema';
 
 @Injectable()
 export class StructuresService {
@@ -106,6 +111,99 @@ export class StructuresService {
     return this.structureModel.find({ deletedAt: { $exists: false }, accountVerified: true }).exec();
   }
 
+  public async findAllFormated(
+    formationCategories: CategoriesFormations[],
+    accompagnementCategories: CategoriesAccompagnement[],
+    otherCategories: CategoriesOthers[]
+  ): Promise<StructureDocument[]> {
+    const structures = await this.structureModel.find({ deletedAt: { $exists: false } }).exec();
+
+    // Update structures coord and address before sending them
+    await Promise.all(
+      structures.map((structure: StructureDocument) => {
+        // If structre has no address, add it
+        if (!structure.address || structure.coord.length <= 0) {
+          return this.getStructurePosition(structure).then((postition: StructureDocument) => {
+            this.structureModel
+              .findByIdAndUpdate(Types.ObjectId(structure._id), {
+                address: postition.address,
+                coord: postition.coord,
+              })
+              .exec();
+          });
+        }
+      })
+    );
+    return (await this.structureModel.find({ deletedAt: { $exists: false }, accountVerified: true }).exec()).map(
+      (structure) => {
+        structure.proceduresAccompaniment = this.mapModules(
+          structure.proceduresAccompaniment,
+          accompagnementCategories.find((category) => category.name === 'Accompagnement des démarches').modules
+        );
+        structure.labelsQualifications = this.mapModules(
+          structure.labelsQualifications,
+          otherCategories.find((category) => category.name === 'Labels et qualifications').modules
+        );
+        structure.publics = this.mapModules(
+          structure.publics,
+          otherCategories.find((category) => category.name === 'Publics acceptés').modules
+        );
+        structure.accessModality = this.mapModules(
+          structure.accessModality,
+          otherCategories.find((category) => category.name === "Modalités d'accès").modules
+        );
+        structure.publicsAccompaniment = this.mapModules(
+          structure.publicsAccompaniment,
+          otherCategories.find((category) => category.name === 'Accompagnement des publics spécifique').modules
+        );
+        structure.equipmentsAndServices = this.mapModules(
+          structure.equipmentsAndServices,
+          otherCategories.find((category) => category.name === 'Équipements et services proposés').modules
+        );
+        structure.baseSkills = this.mapFormationModules(
+          structure.baseSkills,
+          formationCategories.find((category) => category.name === 'Les compétences de base').modules
+        );
+        structure.accessRight = this.mapFormationModules(
+          structure.accessRight,
+          formationCategories.find((category) => category.name === 'Accès aux droits').modules
+        );
+        structure.socialAndProfessional = this.mapFormationModules(
+          structure.socialAndProfessional,
+          formationCategories.find((category) => category.name === 'Insertion sociale et professionnelle').modules
+        );
+        structure.parentingHelp = this.mapFormationModules(
+          structure.parentingHelp,
+          formationCategories.find((category) => category.name === 'Aide à la parentalité').modules
+        );
+        structure.digitalCultureSecurity = this.mapFormationModules(
+          structure.digitalCultureSecurity,
+          formationCategories.find((category) => category.name === 'Culture et sécurité numérique').modules
+        );
+        return structure;
+      }
+    );
+  }
+
+  public mapFormationModules(structureModule: string[], baseModule: CategoriesFormationsModule[]): string[] {
+    if (structureModule == []) {
+      return [];
+    }
+    return structureModule.map((id) => {
+      const formatedText = baseModule.find((module) => module.display_id === id)?.text;
+      return formatedText ? formatedText : id;
+    });
+  }
+  public mapModules(structureModule: string[], baseModule: CategoriesModule[]): string[] {
+    if (structureModule == []) {
+      return [];
+    }
+    return structureModule.map((id) => {
+      const formatedText = baseModule.find((module) => module.id === id)?.text;
+      return formatedText ? formatedText : id;
+    });
+  }
+
   public async update(idStructure: string, structure: structureDto): Promise<Structure> {
     const oldStructure = await this.findOne(idStructure);
     if (!_.isEqual(oldStructure.address, structure.address)) {
diff --git a/src/structures/structures.controller.ts b/src/structures/structures.controller.ts
index 67e12c9a1..9c6283a24 100644
--- a/src/structures/structures.controller.ts
+++ b/src/structures/structures.controller.ts
@@ -15,6 +15,9 @@ import {
 import { ApiParam } from '@nestjs/swagger';
 import { Types } from 'mongoose';
 import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
+import { CategoriesAccompagnementService } from '../categories/services/categories-accompagnement.service';
+import { CategoriesFormationsService } from '../categories/services/categories-formations.service';
+import { CategoriesOthersService } from '../categories/services/categories-others.service';
 import { CreateTempUserDto } from '../temp-user/dto/create-temp-user.dto';
 import { TempUserService } from '../temp-user/temp-user.service';
 import { Roles } from '../users/decorators/roles.decorator';
@@ -33,7 +36,10 @@ export class StructuresController {
     private readonly httpService: HttpService,
     private readonly structureService: StructuresService,
     private readonly userService: UsersService,
-    private readonly tempUserService: TempUserService
+    private readonly tempUserService: TempUserService,
+    private readonly categoriesFormationsService: CategoriesFormationsService,
+    private readonly categoriesOthersService: CategoriesOthersService,
+    private readonly categoriesAccompagnementService: CategoriesAccompagnementService
   ) {}
 
   /**
@@ -79,6 +85,14 @@ export class StructuresController {
     return this.structureService.findAll();
   }
 
+  @Get('formated')
+  public async findAllFormated(): Promise<Structure[]> {
+    const formationCategories = await this.categoriesFormationsService.findAll();
+    const accompagnementCategories = await this.categoriesAccompagnementService.findAll();
+    const otherCategories = await this.categoriesOthersService.findAll();
+    return this.structureService.findAllFormated(formationCategories, accompagnementCategories, otherCategories);
+  }
+
   @Post(':id/isClaimed')
   public async isClaimed(@Param('id') id: string, @Body() user?: User): Promise<boolean> {
     return this.structureService.isClaimed(id, user);
diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts
index 584333cf2..e9c8b75b5 100644
--- a/src/users/users.controller.spec.ts
+++ b/src/users/users.controller.spec.ts
@@ -1,6 +1,7 @@
 import { HttpModule } from '@nestjs/common';
 import { getModelToken } from '@nestjs/mongoose';
 import { Test, TestingModule } from '@nestjs/testing';
+import { CategoriesModule } from '../categories/categories.module';
 import { ConfigurationModule } from '../configuration/configuration.module';
 import { MailerService } from '../mailer/mailer.service';
 import { Structure } from '../structures/schemas/structure.schema';
-- 
GitLab