diff --git a/src/structures/schemas/structure.schema.ts b/src/structures/schemas/structure.schema.ts index e743d5f2077a9632c3092b8f416e3e58beabeb57..fd37511c445d3b68ae96f96b7c452da02cd57d03 100644 --- a/src/structures/schemas/structure.schema.ts +++ b/src/structures/schemas/structure.schema.ts @@ -131,6 +131,9 @@ export class Structure { @Prop() jaccompagneLesUsagersDansLeursDemarchesEnLigne: boolean; + + @Prop() + deletedAt: Date; } export const StructureSchema = SchemaFactory.createForClass(Structure); diff --git a/src/structures/services/aptic-structures.service.ts b/src/structures/services/aptic-structures.service.ts index 38941c0d725cfdc094378a791ce483cf2e86e8c5..9ba852e91fec49df78d294f94d97fce000ce2cdf 100644 --- a/src/structures/services/aptic-structures.service.ts +++ b/src/structures/services/aptic-structures.service.ts @@ -45,6 +45,7 @@ export class ApticStructuresService { private async createApticStructures(structure: ApticStructure): Promise<any> { this.structureAlreadyExist(structure).then((exist) => { if (!exist) { + Logger.log(`Create structure : ${structure.presence_name}`, 'ApticStructuresService - createApticStructures'); const createdStructure = new this.structureModel(); createdStructure.coord = [structure.gps_lng, structure.gps_lat]; createdStructure.structureName = structure.presence_name; @@ -61,16 +62,17 @@ export class ApticStructuresService { } private async structureAlreadyExist(structure: ApticStructure): Promise<boolean> { - const existingStructure = await this.structureModel + let existingStructure = await this.structureModel .findOne({ structureName: { $regex: structure.presence_name, $options: 'i' }, }) .exec(); + // Check without regex for case like 'TINEBRA*DANIEL/DANIEL/' + if (!existingStructure) { + existingStructure = await this.structureModel.findOne({ structureName: structure.presence_name }).exec(); + } + if (existingStructure) { - Logger.log( - `Cannot create structure, it already exist : ${existingStructure.structureName}`, - 'ApticStructuresService - structureAlreadyExist' - ); // Add aptic label if it's not the case if (!existingStructure.labelsQualifications.includes('passNumerique')) { existingStructure.labelsQualifications.push('passNumerique'); diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts index 0833682530fa366ffe1ddddd7a91c87d34e5d9da..6c979e6ef229b8196cb274d53263be531033660b 100644 --- a/src/structures/services/structures.service.ts +++ b/src/structures/services/structures.service.ts @@ -38,12 +38,18 @@ export class StructuresService { public async search(searchString: string, filters?: Array<any>): Promise<Structure[]> { if (searchString && filters) { return this.structureModel - .find({ $and: [...this.parseFilter(filters), { $text: { $search: searchString } }] }) + .find({ + $and: [...this.parseFilter(filters), { $text: { $search: searchString }, deletedAt: { $exists: false } }], + }) .exec(); } else if (filters) { - return this.structureModel.find({ $or: this.parseFilter(filters) }).exec(); + return this.structureModel + .find({ $and: [{ $or: this.parseFilter(filters), deletedAt: { $exists: false } }] }) + .exec(); } else { - return this.structureModel.find({ $or: [{ $text: { $search: searchString } }] }).exec(); + return this.structureModel + .find({ $and: [{ $or: [{ $text: { $search: searchString }, deletedAt: { $exists: false } }] }] }) + .exec(); } } @@ -63,7 +69,7 @@ export class StructuresService { } public async findAll(): Promise<StructureDocument[]> { - const structures = await this.structureModel.find().exec(); + 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) => { @@ -89,7 +95,7 @@ export class StructuresService { } }) ); - return this.structureModel.find().exec(); + return this.structureModel.find({ deletedAt: { $exists: false } }).exec(); } public async update(idStructure: string, structure: structureDto): Promise<Structure> { @@ -193,7 +199,9 @@ export class StructuresService { uniqueElements.map(async (value) => { return { id: value, - count: await this.structureModel.countDocuments({ [key]: { $elemMatch: { $eq: value } } }).exec(), + count: await this.structureModel + .countDocuments({ $and: [{ [key]: { $elemMatch: { $eq: value } }, deletedAt: { $exists: false } }] }) + .exec(), }; }) ); @@ -206,6 +214,30 @@ export class StructuresService { return this.httpService.get(encodeURI(req)); } + public async deleteOne(id: string): Promise<Structure> { + const structure = await this.structureModel.findById(Types.ObjectId(id)).exec(); + if (!structure) { + throw new HttpException('Invalid structure id', HttpStatus.BAD_REQUEST); + } + structure.deletedAt = DateTime.local().setZone('Europe/Paris').toString(); + this.anonymizeStructure(structure).save(); + return structure; + } + + private anonymizeStructure(structure: StructureDocument): StructureDocument { + structure.contactName = ''; + structure.contactSurname = ''; + structure.contactPhone = ''; + structure.contactMail = ''; + structure.facebook = ''; + structure.twitter = ''; + structure.instagram = ''; + structure.website = ''; + structure.fonction = ''; + structure.gender = ''; + return structure; + } + @Cron(CronExpression.EVERY_DAY_AT_4AM) public async checkOutdatedStructuresInfo(): Promise<void> { const OUTDATED_MONT_TO_CHECK = 6; diff --git a/src/structures/structures.controller.ts b/src/structures/structures.controller.ts index b30dbd828577bb018cf359c7d5c183b2ceebefb9..b301a463f40c505140410986d1d17e69e12e345b 100644 --- a/src/structures/structures.controller.ts +++ b/src/structures/structures.controller.ts @@ -1,7 +1,9 @@ -import { Body, Controller, Get, Param, ParseIntPipe, Post, Put, Query, UseGuards } from '@nestjs/common'; +import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query, UseGuards } from '@nestjs/common'; +import { ApiParam } from '@nestjs/swagger'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { Roles } from '../users/decorators/roles.decorator'; import { IsStructureOwnerGuard } from '../users/guards/isStructureOwner.guard'; +import { RolesGuard } from '../users/guards/roles.guard'; import { User } from '../users/schemas/user.schema'; import { UsersService } from '../users/users.service'; import { CreateStructureDto } from './dto/create-structure.dto'; @@ -76,4 +78,12 @@ export class StructuresController { public async find(@Param('id') id: string) { return this.structureService.findOne(id); } + + @Delete(':id') + @UseGuards(JwtAuthGuard, RolesGuard) + @Roles('admin') + @ApiParam({ name: 'id', type: String, required: true }) + public async delete(@Param('id') id: string) { + return this.structureService.deleteOne(id); + } }