diff --git a/src/configuration/config.ts b/src/configuration/config.ts index c11b20a7bbb05ca05f67cc8d3cb4c717466df65c..7bb9d6f5a8b02c9fc654caa84f5cb74a223c99e9 100644 --- a/src/configuration/config.ts +++ b/src/configuration/config.ts @@ -33,5 +33,9 @@ export const config = { ejs: 'structureOutdatedInfo.ejs', json: 'structureOutdatedInfo.json', }, + apticStructureDuplication: { + ejs: 'apticStructureDuplication.ejs', + json: 'apticStructureDuplication.json', + }, }, }; diff --git a/src/mailer/mail-templates/apticStructureDuplication.ejs b/src/mailer/mail-templates/apticStructureDuplication.ejs new file mode 100644 index 0000000000000000000000000000000000000000..5ac784a9c9e172e1d90179224c78319e5c46fb25 --- /dev/null +++ b/src/mailer/mail-templates/apticStructureDuplication.ejs @@ -0,0 +1,13 @@ +Bonjour,<br /> +<br /> +La fiche structure: <strong><%= name %></strong> a été créée après récupération des données aptic. Elle correspond +potientiellement a la structure existante : <strong><%= duplicatedStructureName %></strong>. +<br /> +<br /> +Cordialement, +<br /> +<br /> +L'équipe RES'in +<br /> +<br /> +Ce mail est un mail automatique. Merci de ne pas y répondre. diff --git a/src/mailer/mail-templates/apticStructureDuplication.json b/src/mailer/mail-templates/apticStructureDuplication.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9e77ef58fb1e582b39f4aac4e7a8fef148ecff --- /dev/null +++ b/src/mailer/mail-templates/apticStructureDuplication.json @@ -0,0 +1,3 @@ +{ + "subject": "Doublon Aptic" +} diff --git a/src/mailer/mail-templates/structureOutdatedInfo.ejs b/src/mailer/mail-templates/structureOutdatedInfo.ejs index 945129e78a76c34c785757aa0aac6678f54dd0d2..49e0fa1eef8672da8248b137ee0cb578cce41c06 100644 --- a/src/mailer/mail-templates/structureOutdatedInfo.ejs +++ b/src/mailer/mail-templates/structureOutdatedInfo.ejs @@ -1,6 +1,15 @@ Bonjour<br /> <br /> -La fiche de votre structure: <strong><%= name %></strong> n'a pas été mise a jour depuis 6mois. +Vous recevez ce message, parce que votre structure <strong><%= name %></strong> est référencée sur RES'in, le réseau des +acteurs de l'inclusion numérique de la Métropole de Lyon. Pouvez-vous nous aider en vérifiant que vos données sont bien +à jour en +<a href="<%= config.protocol %>://<%= config.host %><%= config.port ? ':' + config.port : '' %>/home?id=<%= id %>" + >cliquant ici</a +>. +<br /> +Cordialement, +<br /> +L'équipe RES'in <br /> <br /> Ce mail est un mail automatique. Merci de ne pas y répondre. diff --git a/src/mailer/mailer.service.ts b/src/mailer/mailer.service.ts index 83b2a4ba76ba7684f86caf3998402f22e70fee24..04027e30e550dde3f5b8bb793a89609f4299d87b 100644 --- a/src/mailer/mailer.service.ts +++ b/src/mailer/mailer.service.ts @@ -47,7 +47,7 @@ export class MailerService { }) .subscribe( (body) => { - Logger.log(`Send mail : ${subject} success`, 'Mailer'); + Logger.log(`Send mail - success : ${subject}`, 'Mailer'); return resolve(body); }, (err) => { diff --git a/src/structures/services/aptic-structures.service.ts b/src/structures/services/aptic-structures.service.ts index 9ba852e91fec49df78d294f94d97fce000ce2cdf..f2bd9fdc20670bad14a289eb1a29ddaff6f7cc26 100644 --- a/src/structures/services/aptic-structures.service.ts +++ b/src/structures/services/aptic-structures.service.ts @@ -10,11 +10,13 @@ import { Model } from 'mongoose'; import { Structure, StructureDocument } from '../schemas/structure.schema'; import { ApticStructure } from '../schemas/aptic-structure.schema'; import { Address } from '../schemas/address.schema'; +import { UsersService } from '../../users/users.service'; @Injectable() export class ApticStructuresService { constructor( private readonly httpService: HttpService, + private readonly userService: UsersService, @InjectModel(Structure.name) private structureModel: Model<StructureDocument> ) {} @@ -52,11 +54,10 @@ export class ApticStructuresService { createdStructure.contactPhone = structure.presence_phone; createdStructure.labelsQualifications = ['passNumerique']; // Address - const address = new Address(); - address.street = structure.presence_address; - address.commune = structure.city; - createdStructure.address = address; + createdStructure.address = this.formatAddress(structure); createdStructure.save(); + // Send admin weird structure mail + this.verifyDuplication(createdStructure); } }); } @@ -126,4 +127,33 @@ export class ApticStructuresService { }, }); } + + private async verifyDuplication(createdStructure: StructureDocument): Promise<void> { + const sameAddrStructure = await this.structureModel + .findOne({ + _id: { $ne: createdStructure._id }, + address: createdStructure.address, + }) + .exec(); + if (sameAddrStructure) { + this.userService.sendAdminApticStructureMail(createdStructure.structureName, sameAddrStructure.structureName); + } + } + + /** + * Format aptic structure address + */ + private formatAddress(structure: ApticStructure): Address { + const address = new Address(); + const regexWithSpace = /\d+\s/g; // NOSONAR + const regex = /\d+/g; // NOSONAR + if (structure.presence_address.match(regex)) { + address.numero = structure.presence_address.match(regex)[0]; + address.street = structure.presence_address.replace(regexWithSpace, ''); + } else { + address.street = structure.presence_address; + } + address.commune = structure.city; + return address; + } } diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts index 3d045c107e2166ae60702f7af92ef4390f37bde9..fd99c04e10ae183df7c1833b0d87292ce8a92a7c 100644 --- a/src/structures/services/structures.service.ts +++ b/src/structures/services/structures.service.ts @@ -102,6 +102,8 @@ export class StructuresService { const result = await this.structureModel.findByIdAndUpdate(Types.ObjectId(idStructure), structure).exec(); if (!result) { throw new HttpException('Invalid structure id', HttpStatus.BAD_REQUEST); + } else { + this.userService.removeOutdatedStructureFromArray(idStructure); } return this.findOne(idStructure); } @@ -269,7 +271,7 @@ export class StructuresService { if (user.structureOutdatedMailSent.includes(data.structure._id)) { return; } else { - this.sendOutdatedEmailToUser(data.owner.email, data.structure.structureName); + this.sendOutdatedEmailToUser(data.owner.email, data.structure.structureName, data.structure._id); user.structureOutdatedMailSent.push(data.structure._id); user.save(); } @@ -282,7 +284,7 @@ export class StructuresService { * a new account. * @param user User */ - private async sendOutdatedEmailToUser(userEmail: string, structureName: string): Promise<any> { + private async sendOutdatedEmailToUser(userEmail: string, structureName: string, id: string): Promise<any> { const config = this.mailerService.config; const ejsPath = this.mailerService.getTemplateLocation(config.templates.structureOutdatedInfo.ejs); const jsonConfig = this.mailerService.loadJsonConfig(config.templates.structureOutdatedInfo.json); @@ -290,6 +292,7 @@ export class StructuresService { const html = await ejs.renderFile(ejsPath, { config, name: structureName, + id: id, }); this.mailerService.send(userEmail, jsonConfig.subject, html); } diff --git a/src/users/interfaces/user.interface.ts b/src/users/interfaces/user.interface.ts index 9ca1767ff8679c8263a3d1da920aaa6790828278..312a312561258df14bbb3930506f8070f94feba1 100644 --- a/src/users/interfaces/user.interface.ts +++ b/src/users/interfaces/user.interface.ts @@ -1,4 +1,4 @@ -import { Document } from 'mongoose'; +import { Document, Types } from 'mongoose'; export interface IUser extends Document { readonly _id: string; @@ -15,5 +15,5 @@ export interface IUser extends Document { newEmail: string; structuresLink: string[]; pendingStructuresLink: string[]; - structureOutdatedMailSent: string[]; + structureOutdatedMailSent: Types.ObjectId[]; } diff --git a/src/users/schemas/user.schema.ts b/src/users/schemas/user.schema.ts index 5accf9e7ce8c410006aa1a87e82d98c1d0d62adc..deadfe5a0ca1b1bb0a616a4fe5fed566e8ca3d2b 100644 --- a/src/users/schemas/user.schema.ts +++ b/src/users/schemas/user.schema.ts @@ -1,4 +1,5 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Types } from 'mongoose'; import { UserRole } from '../enum/user-role.enum'; @Schema() export class User { @@ -42,7 +43,7 @@ export class User { pendingStructuresLink: string[]; @Prop({ default: null }) - structureOutdatedMailSent: string[]; + structureOutdatedMailSent: Types.ObjectId[]; } export const UserSchema = SchemaFactory.createForClass(User); diff --git a/src/users/users.service.ts b/src/users/users.service.ts index ca6bdc488f66fa2ab45bdaf2dbedcebce0d75985..920a233da69bc25e390303b463de08a8445b668c 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -3,7 +3,7 @@ import { InjectModel } from '@nestjs/mongoose'; import * as bcrypt from 'bcrypt'; import * as ejs from 'ejs'; import * as crypto from 'crypto'; -import { Model } from 'mongoose'; +import { Model, Types } from 'mongoose'; import { LoginDto } from '../auth/login-dto'; import { CreateUserDto } from './dto/create-user.dto'; import { User } from './schemas/user.schema'; @@ -128,7 +128,6 @@ export class UsersService { /** * Send to all admins validation email for structures * a new account. - * @param user User */ private async sendAdminStructureValidationMail(): Promise<any> { const config = this.mailerService.config; @@ -144,6 +143,25 @@ export class UsersService { }); } + /** + * Send to all admins mail for aptic duplicated data + */ + public async sendAdminApticStructureMail(structureName: string, duplicatedStructureName: string): Promise<any> { + const config = this.mailerService.config; + const ejsPath = this.mailerService.getTemplateLocation(config.templates.apticStructureDuplication.ejs); + const jsonConfig = this.mailerService.loadJsonConfig(config.templates.apticStructureDuplication.json); + + const html = await ejs.renderFile(ejsPath, { + config, + name: structureName, + duplicatedStructureName: duplicatedStructureName, + }); + const admins = await this.getAdmins(); + admins.forEach((admin) => { + this.mailerService.send(admin.email, jsonConfig.subject, html); + }); + } + /** * Send approval email for user * a new account. @@ -371,4 +389,14 @@ export class UsersService { ); } } + + public async removeOutdatedStructureFromArray(structureId: string): Promise<void> { + const users = await this.userModel.find({ structureOutdatedMailSent: Types.ObjectId(structureId) }).exec(); + users.forEach((user) => { + user.structureOutdatedMailSent = user.structureOutdatedMailSent.filter((item) => + Types.ObjectId(structureId).equals(item) + ); + user.save(); + }); + } }